From a31fce3301d0ebe47b00b221cab8bd6ada4e0720 Mon Sep 17 00:00:00 2001 From: DJ2LS Date: Sat, 20 Jan 2024 13:52:35 +0100 Subject: [PATCH] work on data dispatcher --- modem/arq_session_irs.py | 4 ++- modem/data_dispatcher.py | 52 +++++++++++++++++++++++++++++++++++ tests/test_data_dispatcher.py | 33 ++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 modem/data_dispatcher.py create mode 100644 tests/test_data_dispatcher.py diff --git a/modem/arq_session_irs.py b/modem/arq_session_irs.py index 4b52a959..cbdb02e1 100644 --- a/modem/arq_session_irs.py +++ b/modem/arq_session_irs.py @@ -5,6 +5,8 @@ from modem_frametypes import FRAME_TYPE from codec2 import FREEDV_MODE from enum import Enum import time +from data_dispatcher import DataDispatcher + class IRS_State(Enum): NEW = 0 OPEN_ACK_SENT = 1 @@ -191,7 +193,7 @@ class ARQSessionIRS(arq_session.ARQSession): self.set_state(IRS_State.ENDED) self.event_manager.send_arq_session_finished( False, self.id, self.dxcall, True, self.state.name, data=self.received_data, statistics=self.calculate_session_statistics()) - + DataDispatcher().dispatch(self.received_data) else: ack = self.frame_factory.build_arq_burst_ack(self.id, diff --git a/modem/data_dispatcher.py b/modem/data_dispatcher.py new file mode 100644 index 00000000..43b87a4c --- /dev/null +++ b/modem/data_dispatcher.py @@ -0,0 +1,52 @@ +import json +import structlog +class DataDispatcher: + def __init__(self): + self.logger = structlog.get_logger(type(self).__name__) + + # Hardcoded endpoints + self.endpoints = { + "p2pmsg": self.handle_p2pmsg, + "test": self.handle_test, + } + self.default_handler = self.handle_raw # Default handler for unrecognized types + + def log(self, message, isWarning = False): + msg = f"[{type(self).__name__}]: {message}" + logger = self.logger.warn if isWarning else self.logger.info + logger(msg) + + def encapsulate(self, data, type_key="p2pmsg"): + """Encapsulate data into the specified format with the given type key.""" + formatted_data = {type_key: data} + return json.dumps(formatted_data) + + def decapsulate(self, byte_data): + """Decapsulate data from the specified format, returning both the data and the type.""" + try: + json_data = byte_data.decode('utf-8') # Decode byte array to string + parsed_data = json.loads(json_data) + if parsed_data and isinstance(parsed_data, dict): + for key, value in parsed_data.items(): + return key, value # Return type and data + return "raw", byte_data # Treat as raw data if no matching type is found + except (json.JSONDecodeError, UnicodeDecodeError): + return "raw", byte_data # Return original data as raw if there's an error + + def dispatch(self, byte_data): + """Decapsulate and dispatch data to the appropriate endpoint based on its type.""" + type_key, data = self.decapsulate(byte_data) + if type_key in self.endpoints: + self.endpoints[type_key](data) + else: + # Use the default handler for unrecognized types + self.default_handler(data) + + def handle_p2pmsg(self, data): + self.log(f"Handling p2pmsg: {data}") + + def handle_raw(self, data): + self.log(f"Handling raw data: {data}") + + def handle_test(self, data): + self.log(f"Handling test data: {data}") \ No newline at end of file diff --git a/tests/test_data_dispatcher.py b/tests/test_data_dispatcher.py new file mode 100644 index 00000000..6b30c8e8 --- /dev/null +++ b/tests/test_data_dispatcher.py @@ -0,0 +1,33 @@ +import sys +sys.path.append('modem') + +import unittest +from data_dispatcher import DataDispatcher + +class TestDispatcher(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.data_dispatcher = DataDispatcher() + + + def testEncapsulator(self): + message_type = "p2pmsg" + message_data = {"message": "Hello, P2P World!"} + + encapsulated = self.data_dispatcher.encapsulate(message_data, message_type) + type, decapsulated = self.data_dispatcher.decapsulate(encapsulated.encode('utf-8')) + self.assertEqual(type, message_type) + self.assertEqual(decapsulated, message_data) + + def testDispatcher(self): + message_type = "test" + message_data = {"message": "Hello, P2P World!"} + + encapsulated = self.data_dispatcher.encapsulate(message_data, message_type) + self.data_dispatcher.dispatch(encapsulated.encode('utf-8')) + + + +if __name__ == '__main__': + unittest.main()