diff --git a/.idea/runConfigurations/tmtcclient_Disable_Periodic_Print_.xml b/.idea/runConfigurations/tmtcclient_Disable_Periodic_Print_.xml index be75fe2bccdff73b2aead2aaefb4d1f256d6382f..b6645926453ca505e2732cd9a09225e1f7b733cc 100644 --- a/.idea/runConfigurations/tmtcclient_Disable_Periodic_Print_.xml +++ b/.idea/runConfigurations/tmtcclient_Disable_Periodic_Print_.xml @@ -13,7 +13,7 @@ <option name="ADD_SOURCE_ROOTS" value="true" /> <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/obsw_tmtc_client.py" /> - <option name="PARAMETERS" value="-m 3 -s 17 -o 129 -c 1 -t 2.2" /> + <option name="PARAMETERS" value="-m 3 -s 17 -o 130 -c 1 -t 2.2" /> <option name="SHOW_COMMAND_LINE" value="false" /> <option name="EMULATE_TERMINAL" value="true" /> <option name="MODULE_MODE" value="false" /> diff --git a/.idea/runConfigurations/tmtcclient_Enable_Periodic_Print.xml b/.idea/runConfigurations/tmtcclient_Enable_Periodic_Print.xml index 62d76453220579e6f173b981fafee2a4fab08473..b7394cbce13ae7c4f410959e820edcf2c31248c5 100644 --- a/.idea/runConfigurations/tmtcclient_Enable_Periodic_Print.xml +++ b/.idea/runConfigurations/tmtcclient_Enable_Periodic_Print.xml @@ -13,7 +13,7 @@ <option name="ADD_SOURCE_ROOTS" value="true" /> <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> <option name="SCRIPT_NAME" value="$PROJECT_DIR$/obsw_tmtc_client.py" /> - <option name="PARAMETERS" value="-m 3 -s 17 -o 128 -c 1 -t 2.2" /> + <option name="PARAMETERS" value="-m 3 -s 17 -o 129 -c 1 -t 2.2" /> <option name="SHOW_COMMAND_LINE" value="false" /> <option name="EMULATE_TERMINAL" value="true" /> <option name="MODULE_MODE" value="false" /> diff --git a/.idea/runConfigurations/tmtcclient_Run_Time_Stats_OBC_.xml b/.idea/runConfigurations/tmtcclient_Run_Time_Stats_OBC_.xml new file mode 100644 index 0000000000000000000000000000000000000000..8e3e5851b3f02f90adb088bc83c11d659719c433 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_Run_Time_Stats_OBC_.xml @@ -0,0 +1,24 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="tmtcclient Run Time Stats OBC " type="PythonConfigurationType" factoryName="Python" folderName="Serial Core"> + <module name="tmtc" /> + <option name="INTERPRETER_OPTIONS" value="" /> + <option name="PARENT_ENVS" value="true" /> + <envs> + <env name="PYTHONUNBUFFERED" value="1" /> + </envs> + <option name="SDK_HOME" value="" /> + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> + <option name="IS_MODULE_SDK" value="true" /> + <option name="ADD_CONTENT_ROOTS" value="true" /> + <option name="ADD_SOURCE_ROOTS" value="true" /> + <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> + <option name="SCRIPT_NAME" value="$PROJECT_DIR$/obsw_tmtc_client.py" /> + <option name="PARAMETERS" value="-m 3 -s Core -o A0 -c 1 -t 2.5" /> + <option name="SHOW_COMMAND_LINE" value="false" /> + <option name="EMULATE_TERMINAL" value="true" /> + <option name="MODULE_MODE" value="false" /> + <option name="REDIRECT_INPUT" value="false" /> + <option name="INPUT_FILE" value="" /> + <method v="2" /> + </configuration> +</component> \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_Trigger_Exceptions.xml b/.idea/runConfigurations/tmtcclient_Trigger_Exceptions.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8483e91e0c5ee927bf310001149083e5b92467e --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_Trigger_Exceptions.xml @@ -0,0 +1,24 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="tmtcclient Trigger Exceptions" type="PythonConfigurationType" factoryName="Python" folderName="Serial Utility"> + <module name="tmtc" /> + <option name="INTERPRETER_OPTIONS" value="" /> + <option name="PARENT_ENVS" value="true" /> + <envs> + <env name="PYTHONUNBUFFERED" value="1" /> + </envs> + <option name="SDK_HOME" value="" /> + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> + <option name="IS_MODULE_SDK" value="true" /> + <option name="ADD_CONTENT_ROOTS" value="true" /> + <option name="ADD_SOURCE_ROOTS" value="true" /> + <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> + <option name="SCRIPT_NAME" value="$PROJECT_DIR$/obsw_tmtc_client.py" /> + <option name="PARAMETERS" value="-m 3 -s 17 -o 150 -c 1 -t 2.2" /> + <option name="SHOW_COMMAND_LINE" value="false" /> + <option name="EMULATE_TERMINAL" value="true" /> + <option name="MODULE_MODE" value="false" /> + <option name="REDIRECT_INPUT" value="false" /> + <option name="INPUT_FILE" value="" /> + <method v="2" /> + </configuration> +</component> \ No newline at end of file diff --git a/config/obsw_com_config.py b/config/obsw_com_config.py index 3de6c2863cc55bd60f83dc150043fe31ff972d53..93de2bae8f4a290d1d76a0ceba8d4f102e81289b 100644 --- a/config/obsw_com_config.py +++ b/config/obsw_com_config.py @@ -41,8 +41,7 @@ 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) elif g.G_COM_IF == g.ComIF.QEMU: communication_interface = QEMUComIF( - tmtc_printer=tmtc_printer, tm_timeout=g.G_TM_TIMEOUT, - tc_timeout_factor=g.G_TC_SEND_TIMEOUT_FACTOR) + tmtc_printer=tmtc_printer, serial_timeout=g.G_TM_TIMEOUT) else: communication_interface = DummyComIF(tmtc_printer=tmtc_printer) if not communication_interface.valid: diff --git a/gui/obsw_backend_test.py b/gui/obsw_backend_test.py index c21caeec5ea9d5dacbc119a6c49e66b27237083a..d9e6c488a10a2a9c5050d4dd33f328f01d548abb 100644 --- a/gui/obsw_backend_test.py +++ b/gui/obsw_backend_test.py @@ -6,6 +6,7 @@ import logging LOGGER = get_logger() + class TmTcBackend(Process): def __init__(self): from obsw_tmtc_client import TmTcHandler @@ -20,7 +21,7 @@ class TmTcBackend(Process): def listen(self): self.conn = self.listener.accept() - LOGGER.info("TmTcBackend: Connection accepted from %s",str(self.listener.last_accepted)) + LOGGER.info("TmTcBackend: Connection accepted from %s", str(self.listener.last_accepted)) while True: msg = self.conn.recv() # do something with msg diff --git a/gui/obsw_tmtc_gui.py b/gui/obsw_tmtc_gui.py index 8c322d5e8e7f54f2ba7a23b5dd9b6209624db546..5c4ba4c80a2b757aa76f933fa979a974ea7d9ddd 100644 --- a/gui/obsw_tmtc_gui.py +++ b/gui/obsw_tmtc_gui.py @@ -21,6 +21,7 @@ import time LOGGER = get_logger() + # A first simple version has drop down menus to chose all necessary options # which are normally handled by the args parser. # when pressing save, all chosen values get passed to the globals file (OBSW_Config) diff --git a/requirements.txt b/requirements.txt index 4a3f79dd0651dd1e85c8e72f74264a7f5a6cecde..4ac62a18eeebe75e7db2b6cc16666ea926ccad88 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ aiohttp==3.6.2 astroid==2.4.2 async-timeout==3.0.1 -attrs==19.3.0 +attrs==20.2.0 chardet==3.0.4 colorama==0.4.3 cpplint==1.5.4 @@ -9,18 +9,18 @@ crcmod>=1.7 docopt==0.6.2 future==0.18.2 idna==2.10 -iso8601==0.1.12 -isort==5.4.2 +iso8601==0.1.13 +isort==5.6.3 lazy-object-proxy==1.5.1 mccabe==0.6.1 multidict==4.7.6 -pylint>=2.5.3 -PyQt5>=5.15.0 -PyQt5-sip>=12.8.0 +pylint>=2.6.0 +PyQt5>=5.15.1 +PyQt5-sip>=12.8.1 pyserial>=3.4 PyYAML==5.3.1 six==1.15.0 toml==0.10.1 -typing-extensions==3.7.4.2 -wrapt==1.11.2 -yarl==1.5.1 +typing-extensions==3.7.4.3 +wrapt==1.12.1 +yarl==1.6.0 diff --git a/tc/obsw_image_handler.py b/tc/obsw_image_handler.py index aa8a3f08020deee54644c73100e983d5a195787d..5f96ad68b051046aea733aa89bb2321f9c792f3d 100644 --- a/tc/obsw_image_handler.py +++ b/tc/obsw_image_handler.py @@ -1,5 +1,5 @@ from tmtc_core.tc.obsw_pus_tc_base import PusTelecommand, Deque -from tc.obsw_tc_service8 import make_action_id +from tc.obsw_tc_service8 import make_action_id from tmtc_core.utility.obsw_logger import get_logger from config.obsw_config import SW_IMAGE_HANDLER_ID diff --git a/tc/obsw_pus_tc_frame_packer.py b/tc/obsw_pus_tc_frame_packer.py index 71d045feb2fdf3a4565384d88afd0678ee3fa7e7..12447d34e9288af1fcff012337ac936c21d9e0ff 100644 --- a/tc/obsw_pus_tc_frame_packer.py +++ b/tc/obsw_pus_tc_frame_packer.py @@ -49,4 +49,4 @@ def pack_tc_info(tc_list: List[PusTelecommand]) -> List[PusTcInfo]: tc_info_list = list() for tc in tc_list: tc_info_list.append(tc.pack_information()) - return tc_info_list \ No newline at end of file + return tc_info_list diff --git a/tc/obsw_pus_tc_packer.py b/tc/obsw_pus_tc_packer.py index 613044ace236b3acdba7fb62cdb7025671cae346..52152688dad6933afa6fa76d717a9be147d9f736 100644 --- a/tc/obsw_pus_tc_packer.py +++ b/tc/obsw_pus_tc_packer.py @@ -34,7 +34,8 @@ class ServiceQueuePacker: def __init__(self): pass - def pack_service_queue(self, service: Union[int, str], op_code: int, service_queue: TcQueueT): + @staticmethod + def pack_service_queue(service: Union[int, str], op_code: int, service_queue: TcQueueT): if service == 2: return pack_service2_test_into(service_queue) if service == 3: diff --git a/tc/obsw_tc_gps.py b/tc/obsw_tc_gps.py index 9d9e1eb29cd230694aab8ed3129e640c7eaf2f4f..1a047bf304543f8268967c814f068419fd3bfc96 100644 --- a/tc/obsw_tc_gps.py +++ b/tc/obsw_tc_gps.py @@ -11,6 +11,7 @@ from tc.obsw_tc_service2 import pack_mode_data import config.obsw_config as g + def pack_gps_test_into(object_id: bytearray, tc_queue: TcQueueT) -> TcQueueT: if object_id == g.GPS0_DEVICE_ID: gps_string = "GPS0" diff --git a/tc/obsw_tc_service20.py b/tc/obsw_tc_service20.py index 1b316d68e38b0f2750857c2e78392f9968dc1d7e..24ce024e069c49f1b22d4b9c8dfb86ab6bbfa12e 100644 --- a/tc/obsw_tc_service20.py +++ b/tc/obsw_tc_service20.py @@ -14,7 +14,7 @@ from tc.obsw_tc_service200 import pack_mode_data def pack_service20_test_into(tc_queue: Deque, called_externally: bool = False) -> Deque: - #parameter IDs + # parameter IDs parameterID0 = 0 parameterID1 = 1 parameterID2 = 2 @@ -29,33 +29,33 @@ def pack_service20_test_into(tc_queue: Deque, called_externally: bool = False) - command = PusTelecommand(service=200, subservice=1, ssc=2000, app_data=mode_data) tc_queue.appendleft(command.pack_command_tuple()) - #test invalid subservice - #use subservice 130 for invalid subservice check, as this is in use for dump reply - #(and therefore will never be a valid subservice) - #tc_queue.appendleft(("print", "Testing Service 20: Invalid subservice")) - #mode_data = pack_mode_data(object_id, 2, 0) - #command = PusTelecommand(service=20, subservice=130, ssc=810, app_data=mode_data) - #tc_queue.appendleft(command.pack_command_tuple()) - - #test invalid objectid //TODO: do we have an objectid known to be empty (even in future)? - #tc_queue.appendleft(("print", "Testing Service 20: Invalid object ID")) - #mode_data = pack_mode_data(object_id, 2, 0) - #command = PusTelecommand(service=20, subservice=128, ssc=810, app_data=mode_data) - #tc_queue.appendleft(command.pack_command_tuple()) - - #test invalid parameterID for load - #tc_queue.appendleft(("print", "Testing Service 20: Invalid parameter ID for load")) - #mode_data = pack_mode_data(object_id, 2, 0) - #command = PusTelecommand(service=20, subservice=128, ssc=810, app_data=mode_data) - #tc_queue.appendleft(command.pack_command_tuple()) - - #test invalid parameterID for dump - #tc_queue.appendleft(("print", "Testing Service 20: Invalid parameter ID for dump")) - #mode_data = pack_mode_data(object_id, 2, 0) - #command = PusTelecommand(service=20, subservice=129, ssc=810, app_data=mode_data) - #tc_queue.appendleft(command.pack_command_tuple()) - - #test checking Load for uint32_t + # test invalid subservice + # use subservice 130 for invalid subservice check, as this is in use for dump reply + # (and therefore will never be a valid subservice) + # tc_queue.appendleft(("print", "Testing Service 20: Invalid subservice")) + # mode_data = pack_mode_data(object_id, 2, 0) + # command = PusTelecommand(service=20, subservice=130, ssc=810, app_data=mode_data) + # tc_queue.appendleft(command.pack_command_tuple()) + + # test invalid objectid //TODO: do we have an objectid known to be empty (even in future)? + # tc_queue.appendleft(("print", "Testing Service 20: Invalid object ID")) + # mode_data = pack_mode_data(object_id, 2, 0) + # command = PusTelecommand(service=20, subservice=128, ssc=810, app_data=mode_data) + # tc_queue.appendleft(command.pack_command_tuple()) + + # test invalid parameterID for load + # tc_queue.appendleft(("print", "Testing Service 20: Invalid parameter ID for load")) + # mode_data = pack_mode_data(object_id, 2, 0) + # command = PusTelecommand(service=20, subservice=128, ssc=810, app_data=mode_data) + # tc_queue.appendleft(command.pack_command_tuple()) + + # test invalid parameterID for dump + # tc_queue.appendleft(("print", "Testing Service 20: Invalid parameter ID for dump")) + # mode_data = pack_mode_data(object_id, 2, 0) + # command = PusTelecommand(service=20, subservice=129, ssc=810, app_data=mode_data) + # tc_queue.appendleft(command.pack_command_tuple()) + + # test checking Load for uint32_t tc_queue.appendleft(("print", "Testing Service 20: Load uint32_t")) parameter_id = struct.pack(">I", parameterID0) parameter_data = struct.pack(">I", 42) @@ -63,7 +63,7 @@ def pack_service20_test_into(tc_queue: Deque, called_externally: bool = False) - command = PusTelecommand(service=20, subservice=128, ssc=2001, app_data=payload) tc_queue.appendleft(command.pack_command_tuple()) - #test checking Dump for uint32_t + # test checking Dump for uint32_t tc_queue.appendleft(("print", "Testing Service 20: Dump uint32_t")) parameter_id = struct.pack(">I", parameterID0) payload = object_id + parameter_id @@ -101,9 +101,6 @@ def pack_service20_test_into(tc_queue: Deque, called_externally: bool = False) - tc_queue.appendleft(command.pack_command_tuple()) """ - - - """ # set mode on tc_queue.appendleft(("print", "Testing Service 8: Set On Mode")) diff --git a/tc/obsw_tc_service23_sdcard.py b/tc/obsw_tc_service23_sdcard.py index 1bd3a8b792de2b57e6a9885cb7f4f4474ea34c03..ccd07d808c1b253838c2d5e3e4b9322b88c0fdbf 100644 --- a/tc/obsw_tc_service23_sdcard.py +++ b/tc/obsw_tc_service23_sdcard.py @@ -318,14 +318,8 @@ def generate_create_file_srv23_1_packet( max_size_of_app_data, filename, repository_path): LOGGER.error("generate_create_file_srv23_1_packet: Initial data too large!") return None - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator to repository_path - data_to_pack.append(0) - data_to_pack += filename.encode('utf-8') - # Add string terminator to filename - data_to_pack.append(0) - + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) data_to_pack += initial_data return PusTelecommand(service=23, subservice=1, ssc=ssc, app_data=data_to_pack) @@ -339,18 +333,28 @@ def generate_rm_file_srv23_2_packet(filename: str, repository_path: str, @param repository_path: The path where the directory shall be created @param ssc: source sequence count @param object_id: The object ID of the memory handler which manages the file system - :return The TC[23,2] PUS packet + @return The telecommand. """ - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator to repository_path - data_to_pack.append(0) - data_to_pack += filename.encode('utf-8') - # Add string terminator to filename - data_to_pack.append(0) + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) return PusTelecommand(service=23, subservice=2, ssc=ssc, app_data=data_to_pack) +def generate_report_file_attr_srv23_3_packet( + filename: str, repository_path: str, ssc: int, + object_id=g.SD_CARD_HANDLER_ID) -> PusTelecommand: + """ + @param filename: The name of the file to delete + @param repository_path: The path where the directory shall be created + @param ssc: source sequence count + @param object_id: The object ID of the memory handler which manages the file system + @return The telecommand. + """ + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) + return PusTelecommand(service=23, subservice=3, ssc=ssc, app_data=data_to_pack) + + def generate_mkdir_srv23_9_packet(directory_name: str, ssc: int, repository_path: str = "/", object_id: bytearray = g.SD_CARD_HANDLER_ID) -> PusTelecommand: """ @@ -359,15 +363,10 @@ def generate_mkdir_srv23_9_packet(directory_name: str, ssc: int, repository_path @param repository_path: The name of the directory to create @param ssc: source sequence count @param object_id: The object ID of the memory handler which manages the file system - :return + @return The telecommand. """ - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator to repository path - data_to_pack.append(0) - data_to_pack += directory_name.encode('utf-8') - # Add string terminator to directory name - data_to_pack.append(0) + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=directory_name) return PusTelecommand(service=23, subservice=9, ssc=ssc, app_data=data_to_pack) @@ -379,15 +378,10 @@ def generate_rmdir_srv23_10_packet(directory_name: str, repository_path: str, ss @param repository_path: Path to directory dirname @param ssc: source sequence count @param object_id: object ID of the memory handler (e.g. SD Card Handler) - @return The application data field of the (23,10) PUS packet + @return The telecommand. """ - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator of repository path - data_to_pack.append(0) - data_to_pack += directory_name.encode('utf-8') - # Add string terminator of directory name - data_to_pack.append(0) + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=directory_name) return PusTelecommand(service=23, subservice=10, ssc=ssc, app_data=data_to_pack) @@ -395,13 +389,8 @@ def generate_append_to_file_srv23_130_packet( filename: str, repository_path: str, packet_sequence_number: int, ssc: int, file_data: bytearray = bytearray([]), object_id: bytearray = g.SD_CARD_HANDLER_ID) -> PusTelecommand: - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator of repository path - data_to_pack.append(0) - data_to_pack += filename.encode('utf-8') - # Add string terminator of filename - data_to_pack.append(0) + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) data_to_pack += file_data data_to_pack.append(packet_sequence_number >> 8) data_to_pack.append(packet_sequence_number & 0xff) @@ -411,13 +400,8 @@ def generate_append_to_file_srv23_130_packet( def generate_finish_append_to_file_srv23_131_packet( filename: str, repository_path: str, ssc: int, lock_file: bool = False, object_id: bytearray = g.SD_CARD_HANDLER_ID): - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator of repository path - data_to_pack.append(0) - data_to_pack += filename.encode('utf-8') - # Add string terminator of filename - data_to_pack.append(0) + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) data_to_pack.append(lock_file) return PusTelecommand(service=23, subservice=131, ssc=ssc, app_data=data_to_pack) @@ -434,115 +418,55 @@ def generate_read_file_srv23_140_packet( @param object_id: object ID of the memory handler (e.g. SD Card Handler) @return: The application data field of the (23,129) PUS packet """ - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator of repository paht - data_to_pack.append(0) - data_to_pack += filename.encode('utf-8') - # Add string terminator of filename - data_to_pack.append(0) + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) return PusTelecommand(service=23, subservice=140, ssc=ssc, app_data=data_to_pack) -def generate_lock_file_packet(ssc: int, lock: bool, repository_path: str, filename: str, - object_id: bytearray = g.SD_CARD_HANDLER_ID): - data_to_pack = bytearray(object_id) - data_to_pack += repository_path.encode('utf-8') - # Add string terminator of repository paht - data_to_pack.append(0) - data_to_pack += filename.encode('utf-8') - # Add string terminator of filename - data_to_pack.append(0) +def generate_lock_file_srv23_5_6_packet(ssc: int, lock: bool, repository_path: str, + filename: str, object_id: bytearray = g.SD_CARD_HANDLER_ID): + data_to_pack = pack_generic_file_command_header(object_id=object_id, first_path=repository_path, + second_path=filename) if lock: return PusTelecommand(service=23, subservice=5, ssc=ssc, app_data=data_to_pack) else: return PusTelecommand(service=23, subservice=6, ssc=ssc, app_data=data_to_pack) -def pack_service23_commands_into(tc_queue: Deque, op_code: int) -> Deque: +def pack_service23_commands_into(tc_queue: TcQueueT, op_code: int) -> Deque: # sd_handler_id = g.SD_CARD_HANDLER_ID if op_code == 0: - tc_queue.appendleft(("print", "Testing Service 23")) - - tc_queue.append(("print", "Create directory 'test'")) - command = generate_mkdir_srv23_9_packet(directory_name="test", repository_path="/", ssc=2300) - tc_queue.appendleft(command.pack_command_tuple()) - tc_queue.append(("print", "Create subdirectory 'subdir' in 'test'")) - command = generate_mkdir_srv23_9_packet(repository_path="test", ssc=2301, - directory_name="subdir") - tc_queue.appendleft(command.pack_command_tuple()) - - tc_queue.appendleft(("print", "Create test.bin")) - command = generate_create_file_srv23_1_packet( - filename="test.bin", repository_path="test/subdir", ssc=2302, - initial_data=bytearray([0x01, 0x00, 0x01, 0x00]), - max_size_of_app_data=1024) - tc_queue.appendleft(command.pack_command_tuple()) - - tc_queue.appendleft(("print", "Printing file structure.")) - command = generate_print_sd_card_packet(ssc=2300) - tc_queue.appendleft(command.pack_command_tuple()) - - tc_queue.appendleft(("print", "Clearing SD card")) - command = generate_clear_sd_card_packet(ssc=2301) - tc_queue.appendleft(command.pack_command_tuple()) - - tc_queue.appendleft(("print", "Printing file structure")) - command = generate_print_sd_card_packet(ssc=2302) - tc_queue.appendleft(command.pack_command_tuple()) - - # tc_queue.appendleft(("print", "Read data of test.bin")) - # command = generate_read_file_srv23_129_packet("test/subdir", "test.bin", ssc=2303) - # tc_queue.appendleft(command.pack_command_tuple()) - tc_queue.appendleft(("print", "Delete 'test.bin'")) - command = generate_rm_file_srv23_2_packet( - filename="test.bin", repository_path="test/subdir", ssc=2304) - tc_queue.appendleft(command.pack_command_tuple()) - tc_queue.appendleft(("print", "Delete 'subdir' directory")) - command = generate_rmdir_srv23_10_packet(directory_name="subdir", repository_path="test", - ssc=2305) - tc_queue.appendleft(command.pack_command_tuple()) - tc_queue.appendleft(("print", "Delete 'test' directory")) - command = generate_rmdir_srv23_10_packet(directory_name="test", repository_path="/", - ssc=2306) - tc_queue.appendleft(command.pack_command_tuple()) - elif op_code == "A2": - tc_queue.append(("print", "Printing active file system")) - command = generate_print_sd_card_packet(ssc=2300) - tc_queue.appendleft(command.pack_command_tuple()) - elif op_code == "A20": - tc_queue.append(("print", "Clearing active file system")) - command = generate_clear_sd_card_packet(ssc=2300) - tc_queue.appendleft(command.pack_command_tuple()) - elif op_code == "A21": - tc_queue.append(("print", "Formatting active file system")) - command = generate_format_sd_card_packet(ssc=2300) - tc_queue.appendleft(command.pack_command_tuple()) - elif op_code == "C0A": - tc_queue.append(("print", "Generating generic folder structure on AT91")) - generate_generic_folder_structure(tc_queue, init_ssc=0, iobc=False) - elif op_code == "C0I": - tc_queue.append(("print", "Generating generic folder structure on iOBC")) - generate_generic_folder_structure(tc_queue, init_ssc=0, iobc=True) + generate_generic_service_23_test(tc_queue) + elif op_code == "3" or op_code == 3: + LOGGER.info("Press h in the following input requests") + LOGGER.info("to send a command to display the folder structure instead") + (repo_path, filename) = prompt_for_repo_filename() + if repo_path == "" and filename == "h": + tc_queue.appendleft(generate_print_sd_card_packet(ssc=0).pack_command_tuple()) + elif repo_path == "" and filename == "c": + return tc_queue + else: + tc_queue.append(("print", "Requesting file attributes")) + command = generate_report_file_attr_srv23_3_packet( + ssc=0, filename=filename, repository_path=repo_path) + tc_queue.appendleft(command.pack_command_tuple()) elif op_code == "5" or op_code == 5: - LOGGER.info("Press h in the following input requests") - LOGGER.info("to send a command to display the folder sturcture instead") + LOGGER.info("to send a command to display the folder structure instead") (repo_path, filename) = prompt_for_repo_filename() if repo_path == "" and filename == "h": tc_queue.append(("print", "Printing active file system")) - tc_queue.appendleft(generate_print_sd_card_packet(ssc=0)) + tc_queue.appendleft(generate_print_sd_card_packet(ssc=0).pack_command_tuple()) elif repo_path == "" and filename == "c": return tc_queue else: tc_queue.append(("print", "Locking file")) - command = generate_lock_file_packet(0, repository_path=repo_path, filename=filename, - lock=True) + command = generate_lock_file_srv23_5_6_packet(ssc=0, repository_path=repo_path, + filename=filename, lock=True) tc_queue.appendleft(command.pack_command_tuple()) elif op_code == "6" or op_code == 6: - LOGGER.info("Press h in the following input requests to send a command to display the" - "folder sturcture instead") + "folder structure instead") (repo_path, filename) = prompt_for_repo_filename() if repo_path == "" and filename == "h": tc_queue.append(("print", "Printing active file system")) @@ -551,12 +475,78 @@ def pack_service23_commands_into(tc_queue: Deque, op_code: int) -> Deque: return tc_queue else: tc_queue.append(("print", "Unlocking file")) - command = generate_lock_file_packet(0, repository_path=repo_path, filename=filename, - lock=False) + command = generate_lock_file_srv23_5_6_packet(ssc=0, repository_path=repo_path, + filename=filename, lock=False) tc_queue.appendleft(command.pack_command_tuple()) + elif op_code == "A2": + tc_queue.append(("print", "Printing active file system")) + command = generate_print_sd_card_packet(ssc=2300) + tc_queue.appendleft(command.pack_command_tuple()) + elif op_code == "A20": + tc_queue.append(("print", "Clearing active file system")) + command = generate_clear_sd_card_packet(ssc=2300) + tc_queue.appendleft(command.pack_command_tuple()) + elif op_code == "A21": + tc_queue.append(("print", "Formatting active file system")) + command = generate_format_sd_card_packet(ssc=2300) + tc_queue.appendleft(command.pack_command_tuple()) + elif op_code == "C0A": + tc_queue.append(("print", "Generating generic folder structure on AT91")) + generate_generic_folder_structure(tc_queue, init_ssc=0, iobc=False) + elif op_code == "C0I": + tc_queue.append(("print", "Generating generic folder structure on iOBC")) + generate_generic_folder_structure(tc_queue, init_ssc=0, iobc=True) + return tc_queue +def generate_generic_service_23_test(tc_queue: TcQueueT): + tc_queue.appendleft(("print", "Testing Service 23")) + + tc_queue.append(("print", "Create directory 'test'")) + command = generate_mkdir_srv23_9_packet(directory_name="test", repository_path="/", ssc=2300) + tc_queue.appendleft(command.pack_command_tuple()) + tc_queue.append(("print", "Create subdirectory 'subdir' in 'test'")) + command = generate_mkdir_srv23_9_packet(repository_path="test", ssc=2301, + directory_name="subdir") + tc_queue.appendleft(command.pack_command_tuple()) + + tc_queue.appendleft(("print", "Create test.bin")) + command = generate_create_file_srv23_1_packet( + filename="test.bin", repository_path="test/subdir", ssc=2302, + initial_data=bytearray([0x01, 0x00, 0x01, 0x00]), + max_size_of_app_data=1024) + tc_queue.appendleft(command.pack_command_tuple()) + + tc_queue.appendleft(("print", "Printing file structure.")) + command = generate_print_sd_card_packet(ssc=2300) + tc_queue.appendleft(command.pack_command_tuple()) + + tc_queue.appendleft(("print", "Clearing SD card")) + command = generate_clear_sd_card_packet(ssc=2301) + tc_queue.appendleft(command.pack_command_tuple()) + + tc_queue.appendleft(("print", "Printing file structure")) + command = generate_print_sd_card_packet(ssc=2302) + tc_queue.appendleft(command.pack_command_tuple()) + + # tc_queue.appendleft(("print", "Read data of test.bin")) + # command = generate_read_file_srv23_129_packet("test/subdir", "test.bin", ssc=2303) + # tc_queue.appendleft(command.pack_command_tuple()) + tc_queue.appendleft(("print", "Delete 'test.bin'")) + command = generate_rm_file_srv23_2_packet( + filename="test.bin", repository_path="test/subdir", ssc=2304) + tc_queue.appendleft(command.pack_command_tuple()) + tc_queue.appendleft(("print", "Delete 'subdir' directory")) + command = generate_rmdir_srv23_10_packet(directory_name="subdir", repository_path="test", + ssc=2305) + tc_queue.appendleft(command.pack_command_tuple()) + tc_queue.appendleft(("print", "Delete 'test' directory")) + command = generate_rmdir_srv23_10_packet(directory_name="test", repository_path="/", + ssc=2306) + tc_queue.appendleft(command.pack_command_tuple()) + + def calculate_allowed_file_data_size(max_app_data_size: int, filename: str, repository: str): # Subtract two because of '\0' terminators return max_app_data_size - len(filename) - len(repository) - 2 @@ -581,3 +571,14 @@ def prompt_for_repo_filename(): if input_confirmation in ['y', "yes", 1]: input_confirmation = True return repo_path, filename + + +def pack_generic_file_command_header(object_id: bytearray, first_path: str, second_path: str): + data_to_pack = bytearray(object_id) + data_to_pack += first_path.encode('utf-8') + # Add string terminator of repository paht + data_to_pack.append(0) + data_to_pack += second_path.encode('utf-8') + # Add string terminator of filename + data_to_pack.append(0) + return data_to_pack diff --git a/tc/obsw_tc_service5_17.py b/tc/obsw_tc_service5_17.py index 4b4a94aacc0d3ebf71bd1d5f036812adf38a891f..23dbd25701c81f31e544a658d3a617df6f281a03 100644 --- a/tc/obsw_tc_service5_17.py +++ b/tc/obsw_tc_service5_17.py @@ -36,7 +36,7 @@ def pack_service5_test_into(tc_queue: TcQueueT) -> TcQueueT: return tc_queue -def pack_service17_test_into(tc_queue: TcQueueT, op_code: int) -> TcQueueT: +def pack_service17_test_into(tc_queue: TcQueueT, op_code: int = 0) -> TcQueueT: if op_code == 0: tc_queue.appendleft(("print", "Testing Service 17")) # ping test @@ -56,9 +56,9 @@ def pack_service17_test_into(tc_queue: TcQueueT, op_code: int) -> TcQueueT: command = PusTelecommand(service=17, subservice=243, ssc=1702) tc_queue.appendleft(command.pack_command_tuple()) tc_queue.appendleft(("export", "log/tmtc_log_service17.txt")) - elif op_code == 128: - pack_enable_periodic_print_packet(tc_queue, True, 0) elif op_code == 129: + pack_enable_periodic_print_packet(tc_queue, True, 0) + elif op_code == 130: pack_enable_periodic_print_packet(tc_queue, False, 0) elif op_code == 150: pack_trigger_exception_packet(tc_queue, 0) @@ -68,9 +68,9 @@ def pack_service17_test_into(tc_queue: TcQueueT, op_code: int) -> TcQueueT: def pack_enable_periodic_print_packet(tc_queue: TcQueueT, enable: bool, ssc: int): tc_queue.appendleft(("print", "Enabling periodic printout")) if enable: - command = PusTelecommand(service=17, subservice=128, ssc=ssc) - else: command = PusTelecommand(service=17, subservice=129, ssc=ssc) + else: + command = PusTelecommand(service=17, subservice=130, ssc=ssc) tc_queue.appendleft(command.pack_command_tuple()) diff --git a/tc/obsw_tc_service9.py b/tc/obsw_tc_service9.py index 507b57ffbba4723c9661970c4194ed97034a8aee..7970b0e5215faba74de4de94156f4a6236f16e29 100644 --- a/tc/obsw_tc_service9.py +++ b/tc/obsw_tc_service9.py @@ -36,4 +36,4 @@ def pack_service9_test_into(tc_queue: TcQueueT) -> TcQueueT: tc_queue.appendleft(command.pack_command_tuple()) # TODO: Add other time formats here tc_queue.appendleft(("export", "log/tmtc_log_service9.txt")) - return tc_queue \ No newline at end of file + return tc_queue diff --git a/tm/obsw_pus_tm_factory_hook.py b/tm/obsw_pus_tm_factory_hook.py index 29ec55a1af3839f859f7611378c53e58081f76d1..6effae10a4852b37511e9a0d243dc7351e9e5dcf 100644 --- a/tm/obsw_pus_tm_factory_hook.py +++ b/tm/obsw_pus_tm_factory_hook.py @@ -144,4 +144,4 @@ class Service200TM(PusTelemetry): elif self.isModeReply: array.append("Mode") array.append("Submode") - return \ No newline at end of file + return diff --git a/tm/obsw_tm_service_23.py b/tm/obsw_tm_service_23.py index 65cf912b3d08cac2b9c685aaf971400248631ae8..b4668c332ff5c583f286129cbed23a6e5a5dafd3 100644 --- a/tm/obsw_tm_service_23.py +++ b/tm/obsw_tm_service_23.py @@ -1,4 +1,9 @@ +import struct + from tmtc_core.tm.obsw_pus_tm_base import PusTelemetry +from tmtc_core.utility.obsw_logger import get_logger + +LOGGER = get_logger() class Service23TM(PusTelemetry): @@ -7,28 +12,68 @@ class Service23TM(PusTelemetry): def __init__(self, byte_array): super().__init__(byte_array) + if len(self.get_tm_data()) < 4: + LOGGER.error("Service23TM: Invalid packet format!") + return + self.object_id = struct.unpack('!I', self._tm_data[0:4])[0] self.repo_path = "" self.filename = "" + self.file_size = 0 + self.lock_status = False self.data_start_idx = 0 - if self.get_subservice() == 132: - # self.unpack_repo_and_filename() + if self.get_subservice() == 4: + self.unpack_repo_and_filename() + self.unpack_file_attributes() + elif self.get_subservice() == 132: + self.unpack_repo_and_filename() pass def unpack_repo_and_filename(self): repo_path_found = False path_idx_start = 0 - for idx in range(self.MAX_FILENAME_LENGTH + self.MAX_REPOSITORY_LENGTH): - if self._tm_data[idx] == "\0": - repo_bytes = self._tm_data[0:idx-1] + max_len_to_scan = len(self.get_tm_data()) - 4 + for idx in range(4, max_len_to_scan): + if not repo_path_found and self._tm_data[idx] == 0: + repo_bytes = self._tm_data[4:idx] self.repo_path = repo_bytes.decode('utf-8') - print(self.repo_path) path_idx_start = idx + 1 + idx += 1 repo_path_found = True if repo_path_found: - if self._tm_data[idx] == "\0": - filename_bytes = self._tm_data[path_idx_start:idx-1] + if self._tm_data[idx] == 0: + filename_bytes = self._tm_data[path_idx_start:idx] self.filename = filename_bytes.decode('utf-8') - print(self.filename) self.data_start_idx = idx + 1 + break + + def unpack_file_attributes(self): + # Size of file length (4) + lock status (1), adapt if more field are added! + print(len(self.get_tm_data()) - self.data_start_idx) + if len(self.get_tm_data()) - self.data_start_idx != 5: + LOGGER.error("Service23TM: Invalid lenght of file attributes data") + return + self.file_size = struct.unpack('!I', self.get_tm_data()[ + self.data_start_idx: self.data_start_idx + 4])[0] + self.lock_status = self.get_tm_data()[self.data_start_idx + 4] + + def append_telemetry_content(self, content_list: list): + super().append_telemetry_content(content_list) + content_list.append(hex(self.object_id)) + content_list.append(self.repo_path) + content_list.append(self.filename) + if self.get_subservice() == 4: + content_list.append(self.file_size) + if self.lock_status == 0: + content_list.append("No") + else: + content_list.append("Yes") + def append_telemetry_column_headers(self, header_list: list): + super().append_telemetry_column_headers(header_list) + header_list.append("Object ID") + header_list.append("Repo Path") + header_list.append("File Name") + if self.get_subservice() == 4: + header_list.append("File Size") + header_list.append("Locked") diff --git a/tm/obsw_tm_service_3.py b/tm/obsw_tm_service_3.py index 96be1223fc42fdfb94298ffabd993dfdc1434ede..ddb4376333700671b40b2f244a48a4a14f8b691a 100644 --- a/tm/obsw_tm_service_3.py +++ b/tm/obsw_tm_service_3.py @@ -122,8 +122,8 @@ class Service3TM(PusTelemetry): # TODO: size check. sth not right with gps 0 test self.number_of_parameters = 9 self.hk_header = ["Fix Mode", "SV in Fix", "GNSS Week", "Time of Week", "Latitude", - "Longitude", "Mean Sea Altitude", "Position X", "Position Y", "Position Z", - "Velocity X", "Velocity Y", "Velocity Z"] + "Longitude", "Mean Sea Altitude", "Position X", "Position Y", + "Position Z", "Velocity X", "Velocity Y", "Velocity Z"] fix_mode = self._tm_data[4] sv_in_fix = self._tm_data[5] gnss_week = struct.unpack('>H', self._tm_data[6:8])[0] diff --git a/tmtc_core b/tmtc_core index e8708d8ded3537dce1cb8478058b5c66ef71713d..233383842fdaca1480d25ce4568da54e8305ffaa 160000 --- a/tmtc_core +++ b/tmtc_core @@ -1 +1 @@ -Subproject commit e8708d8ded3537dce1cb8478058b5c66ef71713d +Subproject commit 233383842fdaca1480d25ce4568da54e8305ffaa diff --git a/utility/binary_writer.py b/utility/binary_writer.py index 577d7ba0bcf24041f9c8ba5b9f6e2450370d4ecb..c07ab66cdf39ec3d3a3e6aa5c6bdf129d0124079 100644 --- a/utility/binary_writer.py +++ b/utility/binary_writer.py @@ -18,7 +18,6 @@ def main(): with open(file_path, "rb+") as file: # Read the first seven ARM vectors. The sixth one will be replaced. arm_vectors = file.read(4 * 7) - arm_vector_6 = arm_vectors[5*4:5*4 + 4] print("ARM vectors: ") # print(''.join('{:02x}'.format(x) for x in arm_vectors)) for x in range(0, 28, 4): diff --git a/utility/obsw_binary_uploader.py b/utility/obsw_binary_uploader.py index ed98abd04cee4023a57cd6a6a3c7e8dd3b20e034..7f27a9e3f6255ef4cac7671785d2af0ee00f9e31 100644 --- a/utility/obsw_binary_uploader.py +++ b/utility/obsw_binary_uploader.py @@ -19,7 +19,7 @@ import config.obsw_config as g from tmtc_core.utility.obsw_tmtc_printer import TmTcPrinter, DisplayMode from tmtc_core.utility.obsw_logger import get_logger from tmtc_core.sendreceive.obsw_tm_listener import TmListener -from tmtc_core.tm.obsw_pus_tm_factory import PusTelemetryFactory, PusTmQueueT +from tmtc_core.tm.obsw_pus_tm_factory import PusTmQueueT LOGGER = get_logger() @@ -116,13 +116,6 @@ def perform_file_upload(com_if: CommunicationInterface, tmtc_printer: TmTcPrinte # now we calculate the hamming code pass - # Read file as binary file - if file_path != (): - with open(file_path, 'rb') as file: - data_to_read = bytearray(file.read()) - else: - LOGGER.info("Specified path invalid..") - tc_queue = deque() # Delete existing binary file first, otherwise data might be appended to otherwise