From 87457392ea22a92026e9ce24c56574be708b900c Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sat, 21 Sep 2019 17:35:26 +0200 Subject: [PATCH] refactor server/client --- bw_client.py | 93 +++++++++++++++++++++++++++++++--------------- bw_server.py | 22 ++--------- docu/docs/index.md | 8 +++- 3 files changed, 74 insertions(+), 49 deletions(-) diff --git a/bw_client.py b/bw_client.py index a93d0ad..dc8aab9 100644 --- a/bw_client.py +++ b/bw_client.py @@ -32,6 +32,10 @@ logging.debug("BOSWatch client has started ...") logging.debug("Import python modules") import argparse logging.debug("- argparse") +import threading +logging.debug("- threading") +import queue +logging.debug("- queue") import time logging.debug("- time") @@ -39,6 +43,7 @@ logging.debug("Import BOSWatch modules") from boswatch.configYaml import ConfigYAML from boswatch.network.client import TCPClient from boswatch.network.broadcast import BroadcastClient +from boswatch.processManager import ProcessManager from boswatch.decoder.decoder import Decoder from boswatch.utils import header from boswatch.utils import misc @@ -55,6 +60,7 @@ parser = argparse.ArgumentParser(prog="bw_client.py", epilog="""More options you can find in the extern client.ini file in the folder /config""") parser.add_argument("-c", "--config", help="Name to configuration File", required=True) +parser.add_argument("-t", "--test", help="Start Client with testdata-set") args = parser.parse_args() bwConfig = ConfigYAML() @@ -62,10 +68,8 @@ if not bwConfig.loadConfigFile(paths.CONFIG_PATH + args.config): logging.error("cannot load config file") exit(1) - -# ############################# begin client system +# ========== CLIENT CODE ========== try: - ip = bwConfig.get("server", "ip", default="127.0.0.1") port = bwConfig.get("server", "port", default="8080") @@ -75,41 +79,67 @@ try: ip = broadcastClient.serverIP port = broadcastClient.serverPort - bwClient = TCPClient() - if bwClient.connect(ip, port): - - testFile = open(paths.TEST_PATH + "testdata.list", "r") + inputQueue = queue.Queue() + # ========== INPUT CODE ========== + def handleSDRInput(dataQueue, config): + mmProc = ProcessManager("/opt/multimon/multimon-ng", textMode=True) + mmProc.addArgument("-i") + mmProc.addArgument("-a POCSAG1200") + mmProc.addArgument("-t raw") + mmProc.addArgument("./poc1200.raw") + mmProc.start() + mmProc.skipLines(5) while 1: + if not mmProc.isRunning: + logging.warning("multimon was down - try to restart") + mmProc.start() + mmProc.skipLines(5) + line = mmProc.readline() + if line: + dataQueue.put_nowait((line, time.time())) + logging.debug("Add data to queue") + # ========== INPUT CODE ========== - for testData in testFile: + mmThread = threading.Thread(target=handleSDRInput, name="mmReader", args=(inputQueue, bwConfig.get("inputSource"))) + mmThread.daemon = True + mmThread.start() - if (len(testData.rstrip(' \t\n\r')) == 0) or ("#" in testData[0]): - continue + bwClient = TCPClient() + bwClient.connect(ip, port) + while 1: - logging.debug("Test: %s", testData) - bwPacket = Decoder.decode(testData) + if not bwClient.isConnected: + logging.warning("connection to server lost - sleep %d seconds", bwConfig.get("client", "reconnectDelay", default="3")) + time.sleep(bwConfig.get("client", "reconnectDelay", default="3")) + bwClient.connect(ip, port) - if bwPacket: - bwPacket.printInfo() - misc.addClientDataToPacket(bwPacket, bwConfig) - bwClient.transmit(str(bwPacket)) + elif not inputQueue.empty(): + data = inputQueue.get() + logging.info("get data from queue (waited %0.3f sec.)", time.time() - data[1]) + logging.debug("%s packet(s) still waiting in queue", inputQueue.qsize()) - # todo should we do this in an thread, to not block receiving ??? but then we should use transmit() and receive() with Lock() - failedTransmits = 0 - while not bwClient.receive() == "[ack]": # wait for ack or timeout - if failedTransmits >= 3: - logging.error("cannot transmit after 3 retires") - break - failedTransmits += 1 - logging.warning("attempt %d to resend packet", failedTransmits) - bwClient.transmit(str(bwPacket)) # try to resend + bwPacket = Decoder.decode(data[0]) + inputQueue.task_done() + if bwPacket is None: + continue + + bwPacket.printInfo() + misc.addClientDataToPacket(bwPacket, bwConfig) + + for sendCnt in range(bwConfig.get("client", "sendTries", default="3")): + bwClient.transmit(str(bwPacket)) + if bwClient.receive() == "[ack-]": logging.debug("ack ok") + break + logging.warning("cannot send packet - sleep %d seconds", bwConfig.get("client", "sendDelay", default="3")) + time.sleep(bwConfig.get("client", "sendDelay", default="3")) + + else: + time.sleep(0.1) # reduce cpu load (wait 100ms) + # in worst case a packet have to wait 100ms until it will be processed - bwClient.disconnect() - break -# test for server #################################### except KeyboardInterrupt: # pragma: no cover logging.warning("Keyboard interrupt") @@ -117,5 +147,8 @@ except SystemExit: # pragma: no cover logging.error("BOSWatch interrupted by an error") except: # pragma: no cover logging.exception("BOSWatch interrupted by an error") -finally: # pragma: no cover - logging.debug("BOSWatch has ended ...") +finally: + logging.debug("Starting shutdown routine") + bwClient.disconnect() + logging.debug("BOSWatch client has stopped ...") + diff --git a/bw_server.py b/bw_server.py index 42ee541..5564154 100644 --- a/bw_server.py +++ b/bw_server.py @@ -106,23 +106,9 @@ except SystemExit: # pragma: no cover logging.error("BOSWatch interrupted by an error") except: # pragma: no cover logging.exception("BOSWatch interrupted by an error") -finally: # pragma: no cover - +finally: logging.debug("Starting shutdown routine") del bwRoutMan - - try: - bwServer.stop() - except NameError: - pass - except: - raise - - try: - bcServer.stop() - except NameError: - pass - except: - raise - - logging.debug("BOSWatch has ended ...") + bwServer.stop() + bcServer.stop() + logging.debug("BOSWatch server has stopped ...") diff --git a/docu/docs/index.md b/docu/docs/index.md index f62eb8c..a6840b4 100644 --- a/docu/docs/index.md +++ b/docu/docs/index.md @@ -1,7 +1,13 @@ #
BOSWatch 3
--- -
![BOSWatch](img/bw3.png "BOSWatch 3 Logo")
+
+![BOSWatch](img/bw3.png "BOSWatch 3 Logo") + +Falls du uns unterstützen möchtest würden wir uns über eine Spende freuen. +Server, Hosting, Domain sowie Kaffee kosten leider Geld ;-) +[![](https://www.paypalobjects.com/de_DE/DE/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CLK9VBN2MSLZY&source=url) +
**Es wird darauf hingewiesen, dass für die Teilnahme am BOS-Funk nur nach den Technischen Richtlinien der BOS zugelassene Funkanlagen verwendet werden dürfen.** **Der BOS-Funk ist ein nichtöffentlicher mobiler Landfunk. Privatpersonen gehören nicht zum Kreis der berechtigten Funkteilnehmer.** _(Quelle: TR-BOS)_