openc3 5.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +18 -0
- data/Guardfile +35 -0
- data/LICENSE.txt +727 -0
- data/README.md +37 -0
- data/Rakefile +131 -0
- data/bin/cstol_converter +1178 -0
- data/bin/openc3cli +531 -0
- data/bin/rubysloc +139 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +214 -0
- data/data/config/_interfaces.yaml.err +1017 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +60 -0
- data/data/config/cmd_tlm_server.yaml +136 -0
- data/data/config/command.yaml +44 -0
- data/data/config/command_modifiers.yaml +160 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/interface_modifiers.yaml +104 -0
- data/data/config/item_modifiers.yaml +221 -0
- data/data/config/microservice.yaml +78 -0
- data/data/config/param_item_modifiers.yaml +52 -0
- data/data/config/parameter_modifiers.yaml +200 -0
- data/data/config/plugins.yaml +80 -0
- data/data/config/protocols.yaml +290 -0
- data/data/config/screen.yaml +147 -0
- data/data/config/table_manager.yaml +89 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +142 -0
- data/data/config/target_config.yaml +94 -0
- data/data/config/telemetry.yaml +87 -0
- data/data/config/telemetry_modifiers.yaml +159 -0
- data/data/config/tool.yaml +63 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1505 -0
- data/ext/mkrf_conf.rb +49 -0
- data/ext/openc3/ext/array/array.c +122 -0
- data/ext/openc3/ext/array/extconf.rb +13 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
- data/ext/openc3/ext/config_parser/config_parser.c +280 -0
- data/ext/openc3/ext/config_parser/extconf.rb +13 -0
- data/ext/openc3/ext/crc/crc.c +351 -0
- data/ext/openc3/ext/crc/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
- data/ext/openc3/ext/packet/extconf.rb +13 -0
- data/ext/openc3/ext/packet/packet.c +318 -0
- data/ext/openc3/ext/platform/extconf.rb +13 -0
- data/ext/openc3/ext/platform/platform.c +134 -0
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
- data/ext/openc3/ext/string/extconf.rb +13 -0
- data/ext/openc3/ext/string/string.c +63 -0
- data/ext/openc3/ext/structure/structure.c +1719 -0
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
- data/ext/openc3/ext/telemetry/extconf.rb +13 -0
- data/ext/openc3/ext/telemetry/telemetry.c +336 -0
- data/lib/cosmos.rb +20 -0
- data/lib/cosmosc2.rb +20 -0
- data/lib/openc3/api/api.rb +39 -0
- data/lib/openc3/api/authorized_api.rb +30 -0
- data/lib/openc3/api/cmd_api.rb +451 -0
- data/lib/openc3/api/config_api.rb +58 -0
- data/lib/openc3/api/interface_api.rb +117 -0
- data/lib/openc3/api/limits_api.rb +375 -0
- data/lib/openc3/api/router_api.rb +117 -0
- data/lib/openc3/api/settings_api.rb +70 -0
- data/lib/openc3/api/target_api.rb +78 -0
- data/lib/openc3/api/tlm_api.rb +455 -0
- data/lib/openc3/bridge/bridge.rb +54 -0
- data/lib/openc3/bridge/bridge_config.rb +167 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
- data/lib/openc3/config/config_parser.rb +549 -0
- data/lib/openc3/config/meta_config_parser.rb +74 -0
- data/lib/openc3/conversions/conversion.rb +70 -0
- data/lib/openc3/conversions/generic_conversion.rb +83 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
- data/lib/openc3/conversions/processor_conversion.rb +70 -0
- data/lib/openc3/conversions/received_count_conversion.rb +38 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
- data/lib/openc3/conversions.rb +34 -0
- data/lib/openc3/core_ext/array.rb +416 -0
- data/lib/openc3/core_ext/binding.rb +29 -0
- data/lib/openc3/core_ext/class.rb +72 -0
- data/lib/openc3/core_ext/exception.rb +61 -0
- data/lib/openc3/core_ext/file.rb +83 -0
- data/lib/openc3/core_ext/hash.rb +37 -0
- data/lib/openc3/core_ext/io.rb +134 -0
- data/lib/openc3/core_ext/kernel.rb +42 -0
- data/lib/openc3/core_ext/math.rb +128 -0
- data/lib/openc3/core_ext/matrix.rb +156 -0
- data/lib/openc3/core_ext/objectspace.rb +36 -0
- data/lib/openc3/core_ext/openc3_io.rb +57 -0
- data/lib/openc3/core_ext/range.rb +27 -0
- data/lib/openc3/core_ext/socket.rb +38 -0
- data/lib/openc3/core_ext/string.rb +389 -0
- data/lib/openc3/core_ext/stringio.rb +33 -0
- data/lib/openc3/core_ext/time.rb +508 -0
- data/lib/openc3/core_ext.rb +36 -0
- data/lib/openc3/interfaces/interface.rb +498 -0
- data/lib/openc3/interfaces/linc_interface.rb +475 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
- data/lib/openc3/interfaces/serial_interface.rb +94 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
- data/lib/openc3/interfaces/stream_interface.rb +81 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
- data/lib/openc3/interfaces/udp_interface.rb +169 -0
- data/lib/openc3/interfaces.rb +44 -0
- data/lib/openc3/io/buffered_file.rb +109 -0
- data/lib/openc3/io/io_multiplexer.rb +80 -0
- data/lib/openc3/io/json_api_object.rb +208 -0
- data/lib/openc3/io/json_drb.rb +335 -0
- data/lib/openc3/io/json_drb_object.rb +114 -0
- data/lib/openc3/io/json_drb_rack.rb +84 -0
- data/lib/openc3/io/json_rpc.rb +420 -0
- data/lib/openc3/io/openc3_snmp.rb +58 -0
- data/lib/openc3/io/posix_serial_driver.rb +156 -0
- data/lib/openc3/io/raw_logger.rb +167 -0
- data/lib/openc3/io/raw_logger_pair.rb +77 -0
- data/lib/openc3/io/serial_driver.rb +105 -0
- data/lib/openc3/io/stderr.rb +43 -0
- data/lib/openc3/io/stdout.rb +43 -0
- data/lib/openc3/io/udp_sockets.rb +194 -0
- data/lib/openc3/io/win32_serial_driver.rb +196 -0
- data/lib/openc3/logs/log_writer.rb +302 -0
- data/lib/openc3/logs/packet_log_constants.rb +62 -0
- data/lib/openc3/logs/packet_log_reader.rb +345 -0
- data/lib/openc3/logs/packet_log_writer.rb +299 -0
- data/lib/openc3/logs/text_log_writer.rb +68 -0
- data/lib/openc3/logs.rb +25 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
- data/lib/openc3/microservices/decom_microservice.rb +136 -0
- data/lib/openc3/microservices/interface_microservice.rb +532 -0
- data/lib/openc3/microservices/log_microservice.rb +108 -0
- data/lib/openc3/microservices/microservice.rb +204 -0
- data/lib/openc3/microservices/plugin_microservice.rb +43 -0
- data/lib/openc3/microservices/reaction_microservice.rb +541 -0
- data/lib/openc3/microservices/reducer_microservice.rb +313 -0
- data/lib/openc3/microservices/router_microservice.rb +44 -0
- data/lib/openc3/microservices/text_log_microservice.rb +84 -0
- data/lib/openc3/microservices/timeline_microservice.rb +363 -0
- data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
- data/lib/openc3/models/activity_model.rb +319 -0
- data/lib/openc3/models/auth_model.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +185 -0
- data/lib/openc3/models/environment_model.rb +58 -0
- data/lib/openc3/models/gem_model.rb +137 -0
- data/lib/openc3/models/info_model.rb +31 -0
- data/lib/openc3/models/interface_model.rb +281 -0
- data/lib/openc3/models/interface_status_model.rb +117 -0
- data/lib/openc3/models/metadata_model.rb +139 -0
- data/lib/openc3/models/metric_model.rb +59 -0
- data/lib/openc3/models/microservice_model.rb +206 -0
- data/lib/openc3/models/microservice_status_model.rb +74 -0
- data/lib/openc3/models/model.rb +204 -0
- data/lib/openc3/models/note_model.rb +122 -0
- data/lib/openc3/models/notification_model.rb +40 -0
- data/lib/openc3/models/ping_model.rb +35 -0
- data/lib/openc3/models/plugin_model.rb +292 -0
- data/lib/openc3/models/process_status_model.rb +76 -0
- data/lib/openc3/models/reaction_model.rb +322 -0
- data/lib/openc3/models/reducer_model.rb +65 -0
- data/lib/openc3/models/router_model.rb +35 -0
- data/lib/openc3/models/router_status_model.rb +27 -0
- data/lib/openc3/models/scope_model.rb +153 -0
- data/lib/openc3/models/settings_model.rb +55 -0
- data/lib/openc3/models/sorted_model.rb +167 -0
- data/lib/openc3/models/target_model.rb +759 -0
- data/lib/openc3/models/timeline_model.rb +154 -0
- data/lib/openc3/models/tool_config_model.rb +38 -0
- data/lib/openc3/models/tool_model.rb +262 -0
- data/lib/openc3/models/trigger_group_model.rb +186 -0
- data/lib/openc3/models/trigger_model.rb +330 -0
- data/lib/openc3/models/widget_model.rb +138 -0
- data/lib/openc3/operators/microservice_operator.rb +128 -0
- data/lib/openc3/operators/operator.rb +277 -0
- data/lib/openc3/packets/binary_accessor.rb +1207 -0
- data/lib/openc3/packets/commands.rb +373 -0
- data/lib/openc3/packets/json_packet.rb +134 -0
- data/lib/openc3/packets/limits.rb +271 -0
- data/lib/openc3/packets/limits_response.rb +53 -0
- data/lib/openc3/packets/packet.rb +1168 -0
- data/lib/openc3/packets/packet_config.rb +625 -0
- data/lib/openc3/packets/packet_item.rb +586 -0
- data/lib/openc3/packets/packet_item_limits.rb +162 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
- data/lib/openc3/packets/parsers/state_parser.rb +127 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
- data/lib/openc3/packets/structure.rb +553 -0
- data/lib/openc3/packets/structure_item.rb +365 -0
- data/lib/openc3/packets/telemetry.rb +487 -0
- data/lib/openc3/processors/processor.rb +86 -0
- data/lib/openc3/processors/statistics_processor.rb +82 -0
- data/lib/openc3/processors/watermark_processor.rb +58 -0
- data/lib/openc3/processors.rb +24 -0
- data/lib/openc3/script/api_shared.rb +828 -0
- data/lib/openc3/script/calendar.rb +89 -0
- data/lib/openc3/script/commands.rb +227 -0
- data/lib/openc3/script/exceptions.rb +29 -0
- data/lib/openc3/script/extract.rb +161 -0
- data/lib/openc3/script/limits.rb +60 -0
- data/lib/openc3/script/script.rb +299 -0
- data/lib/openc3/script/script_runner.rb +238 -0
- data/lib/openc3/script/storage.rb +146 -0
- data/lib/openc3/script/suite.rb +542 -0
- data/lib/openc3/script/suite_results.rb +196 -0
- data/lib/openc3/script/suite_runner.rb +217 -0
- data/lib/openc3/script.rb +21 -0
- data/lib/openc3/streams/serial_stream.rb +167 -0
- data/lib/openc3/streams/stream.rb +63 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
- data/lib/openc3/system/system.rb +127 -0
- data/lib/openc3/system/system_config.rb +411 -0
- data/lib/openc3/system/target.rb +269 -0
- data/lib/openc3/system.rb +24 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
- data/lib/openc3/tools/table_manager/table.rb +77 -0
- data/lib/openc3/tools/table_manager/table_config.rb +273 -0
- data/lib/openc3/tools/table_manager/table_item.rb +90 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
- data/lib/openc3/tools/test_runner/test.rb +67 -0
- data/lib/openc3/top_level.rb +595 -0
- data/lib/openc3/topics/autonomic_topic.rb +52 -0
- data/lib/openc3/topics/calendar_topic.rb +44 -0
- data/lib/openc3/topics/command_decom_topic.rb +76 -0
- data/lib/openc3/topics/command_topic.rb +83 -0
- data/lib/openc3/topics/config_topic.rb +68 -0
- data/lib/openc3/topics/interface_topic.rb +73 -0
- data/lib/openc3/topics/limits_event_topic.rb +109 -0
- data/lib/openc3/topics/notifications_topic.rb +28 -0
- data/lib/openc3/topics/router_topic.rb +85 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
- data/lib/openc3/topics/telemetry_topic.rb +36 -0
- data/lib/openc3/topics/timeline_topic.rb +45 -0
- data/lib/openc3/topics/topic.rb +53 -0
- data/lib/openc3/utilities/authentication.rb +141 -0
- data/lib/openc3/utilities/authorization.rb +51 -0
- data/lib/openc3/utilities/crc.rb +278 -0
- data/lib/openc3/utilities/csv.rb +153 -0
- data/lib/openc3/utilities/logger.rb +187 -0
- data/lib/openc3/utilities/message_log.rb +91 -0
- data/lib/openc3/utilities/metric.rb +141 -0
- data/lib/openc3/utilities/process_manager.rb +139 -0
- data/lib/openc3/utilities/quaternion.rb +257 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
- data/lib/openc3/utilities/s3.rb +202 -0
- data/lib/openc3/utilities/s3_autoload.rb +9 -0
- data/lib/openc3/utilities/s3_file_cache.rb +274 -0
- data/lib/openc3/utilities/simulated_target.rb +117 -0
- data/lib/openc3/utilities/sleeper.rb +51 -0
- data/lib/openc3/utilities/store.rb +23 -0
- data/lib/openc3/utilities/store_autoload.rb +237 -0
- data/lib/openc3/utilities/zip.rb +21 -0
- data/lib/openc3/utilities.rb +35 -0
- data/lib/openc3/version.rb +14 -0
- data/lib/openc3/win32/excel.rb +132 -0
- data/lib/openc3/win32/win32.rb +402 -0
- data/lib/openc3/win32/win32_main.rb +333 -0
- data/lib/openc3.rb +49 -0
- data/tasks/gemfile_stats.rake +113 -0
- data/tasks/spec.rake +30 -0
- data/templates/plugin-template/README.md +15 -0
- data/templates/plugin-template/Rakefile +12 -0
- data/templates/plugin-template/plugin.gemspec +23 -0
- data/templates/plugin-template/plugin.txt +9 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
- data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
- data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
- data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
- data/templates/plugin-template/targets/TARGET/target.txt +5 -0
- metadata +849 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
module OpenC3
|
|
21
|
+
autoload(:Target, "openc3/system/target.rb")
|
|
22
|
+
autoload(:System, "openc3/system/system.rb")
|
|
23
|
+
autoload(:SystemConfig, "openc3/system/system_config.rb")
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
require 'openc3/api/api'
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
require 'openc3/config/config_parser'
|
|
21
|
+
|
|
22
|
+
module OpenC3
|
|
23
|
+
# Reads an ascii file that defines the configuration settings used to
|
|
24
|
+
# configure the Command/Telemetry Server.
|
|
25
|
+
class CmdTlmServerConfig
|
|
26
|
+
# @return [Hash<String, Interface>] Interfaces hash
|
|
27
|
+
attr_accessor :interfaces
|
|
28
|
+
# @return [Hash<String, Interface>] Routers hash
|
|
29
|
+
attr_accessor :routers
|
|
30
|
+
# @return [Hash<String, PacketLogWriterPair>] Packet log writer hash. Each
|
|
31
|
+
# pair encapsulates a command and telemetry log writer.
|
|
32
|
+
attr_accessor :packet_log_writer_pairs
|
|
33
|
+
# @return [Array<BackgroundTask>] Array of background tasks
|
|
34
|
+
attr_accessor :background_tasks
|
|
35
|
+
# @return [String] Command and Telemetry Server title
|
|
36
|
+
attr_accessor :title
|
|
37
|
+
# @return [Boolean] Flag indicating if meta data should be collected
|
|
38
|
+
attr_accessor :metadata
|
|
39
|
+
|
|
40
|
+
# Create a default pair of packet log writers and parses the
|
|
41
|
+
# configuration file.
|
|
42
|
+
#
|
|
43
|
+
# @param filename [String] The name of the configuration file to parse
|
|
44
|
+
def initialize(filename, system_config)
|
|
45
|
+
@system_config = system_config
|
|
46
|
+
@interfaces = {}
|
|
47
|
+
@routers = {}
|
|
48
|
+
@packet_log_writer_pairs = {}
|
|
49
|
+
# cmd_log_writer = System.default_packet_log_writer.new(:CMD, *System.default_packet_log_writer_params)
|
|
50
|
+
# tlm_log_writer = System.default_packet_log_writer.new(:TLM, *System.default_packet_log_writer_params)
|
|
51
|
+
# @packet_log_writer_pairs['DEFAULT'] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
|
|
52
|
+
@background_tasks = []
|
|
53
|
+
@title = nil
|
|
54
|
+
@metadata = false
|
|
55
|
+
process_file(filename)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
|
|
60
|
+
def get_target_interface_name(target_name)
|
|
61
|
+
@interfaces.each do |interface_name, interface|
|
|
62
|
+
return interface_name if interface.target_names.include?(target_name)
|
|
63
|
+
end
|
|
64
|
+
nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def setup_interface_or_router
|
|
68
|
+
current_interface_or_router = OpenStruct.new
|
|
69
|
+
current_interface_or_router.interfaces = []
|
|
70
|
+
current_interface_or_router.routers = []
|
|
71
|
+
current_interface_or_router.target_names = []
|
|
72
|
+
current_interface_or_router
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Processes a file and adds in the configuration defined in the file
|
|
76
|
+
#
|
|
77
|
+
# @param filename [String] The name of the configuration file to parse
|
|
78
|
+
# @param recursive [Boolean] Whether process_file is being called
|
|
79
|
+
# recursively
|
|
80
|
+
def process_file(filename, recursive = false)
|
|
81
|
+
current_interface_or_router = nil
|
|
82
|
+
current_type = nil
|
|
83
|
+
current_interface_log_added = false
|
|
84
|
+
|
|
85
|
+
Logger.info "Processing CmdTlmServer configuration in file: #{File.expand_path(filename)}"
|
|
86
|
+
|
|
87
|
+
parser = ConfigParser.new("https://openc3.com/docs/v5")
|
|
88
|
+
parser.parse_file(filename) do |keyword, params|
|
|
89
|
+
case keyword
|
|
90
|
+
when 'TITLE'
|
|
91
|
+
raise parser.error("#{keyword} not allowed in target #{filename}") if recursive
|
|
92
|
+
|
|
93
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Title Text>")
|
|
94
|
+
@title = params[0]
|
|
95
|
+
|
|
96
|
+
when 'PACKET_LOG_WRITER'
|
|
97
|
+
# usage = "PACKET_LOG_WRITER <Name> <Filename> <Specific Parameters>"
|
|
98
|
+
# parser.verify_num_parameters(2, nil, usage)
|
|
99
|
+
# packet_log_writer_name = params[0].upcase
|
|
100
|
+
# packet_log_writer_class = OpenC3.require_class(params[1])
|
|
101
|
+
|
|
102
|
+
# # Verify not overridding a packet log writer that is already associated with an interface
|
|
103
|
+
# packet_log_writer_pair = @packet_log_writer_pairs[packet_log_writer_name]
|
|
104
|
+
# if packet_log_writer_pair
|
|
105
|
+
# @interfaces.each do |interface_name, interface|
|
|
106
|
+
# if interface.packet_log_writer_pairs.include?(packet_log_writer_pair)
|
|
107
|
+
# raise parser.error("Redefining Packet Log Writer #{packet_log_writer_name} not allowed after it is associated with an interface")
|
|
108
|
+
# end
|
|
109
|
+
# end
|
|
110
|
+
# end
|
|
111
|
+
|
|
112
|
+
# if params[2]
|
|
113
|
+
# cmd_log_writer = packet_log_writer_class.new(:CMD, *params[2..-1])
|
|
114
|
+
# tlm_log_writer = packet_log_writer_class.new(:TLM, *params[2..-1])
|
|
115
|
+
# @packet_log_writer_pairs[packet_log_writer_name] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
|
|
116
|
+
# else
|
|
117
|
+
# cmd_log_writer = packet_log_writer_class.new(:CMD)
|
|
118
|
+
# tlm_log_writer = packet_log_writer_class.new(:TLM)
|
|
119
|
+
# @packet_log_writer_pairs[packet_log_writer_name] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
|
|
120
|
+
# end
|
|
121
|
+
|
|
122
|
+
when 'AUTO_INTERFACE_TARGETS'
|
|
123
|
+
raise parser.error("#{keyword} not allowed in target #{filename}") if recursive
|
|
124
|
+
|
|
125
|
+
usage = "#{keyword}"
|
|
126
|
+
parser.verify_num_parameters(0, 0, usage)
|
|
127
|
+
@system_config.targets.each do |target_name, target|
|
|
128
|
+
target_filename = File.join(target.dir, 'cmd_tlm_server.txt')
|
|
129
|
+
if File.exist?(target_filename)
|
|
130
|
+
# Skip this target if it's already been assigned an interface
|
|
131
|
+
next if get_target_interface_name(target.name)
|
|
132
|
+
raise parser.error("Cannot use #{keyword} with target name substitutions: #{target.name} != #{target.original_name}") if target.name != target.original_name
|
|
133
|
+
|
|
134
|
+
process_file(target_filename, true)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
when 'INTERFACE_TARGET'
|
|
139
|
+
raise parser.error("#{keyword} not allowed in target #{filename}") if recursive
|
|
140
|
+
|
|
141
|
+
usage = "#{keyword} <Target Name> <Config File (defaults to cmd_tlm_server.txt)>"
|
|
142
|
+
parser.verify_num_parameters(1, 2, usage)
|
|
143
|
+
target = @system_config.targets[params[0].upcase]
|
|
144
|
+
raise parser.error("Unknown target: #{params[0].upcase}") unless target
|
|
145
|
+
|
|
146
|
+
interface_name = get_target_interface_name(target.name)
|
|
147
|
+
raise parser.error("Target #{target.name} already mapped to interface #{interface_name}") if interface_name
|
|
148
|
+
|
|
149
|
+
target_filename = params[1]
|
|
150
|
+
target_filename = 'cmd_tlm_server.txt' unless target_filename
|
|
151
|
+
target_filename = File.join(target.dir, target_filename)
|
|
152
|
+
if File.exist?(target_filename)
|
|
153
|
+
process_file(target_filename, true)
|
|
154
|
+
else
|
|
155
|
+
raise parser.error("#{target_filename} does not exist")
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
when 'INTERFACE'
|
|
159
|
+
usage = "INTERFACE <Name> <Filename> <Specific Parameters>"
|
|
160
|
+
parser.verify_num_parameters(2, nil, usage)
|
|
161
|
+
interface_name = params[0].upcase
|
|
162
|
+
raise parser.error("Interface '#{interface_name}' defined twice") if @interfaces[interface_name]
|
|
163
|
+
|
|
164
|
+
# interface_class = OpenC3.require_class(params[1])
|
|
165
|
+
# if params[2]
|
|
166
|
+
# current_interface_or_router = interface_class.new(*params[2..-1])
|
|
167
|
+
# else
|
|
168
|
+
# current_interface_or_router = interface_class.new
|
|
169
|
+
# end
|
|
170
|
+
current_interface_or_router = setup_interface_or_router()
|
|
171
|
+
current_type = :INTERFACE
|
|
172
|
+
current_interface_log_added = false
|
|
173
|
+
# current_interface_or_router.packet_log_writer_pairs << @packet_log_writer_pairs['DEFAULT']
|
|
174
|
+
current_interface_or_router.name = interface_name
|
|
175
|
+
current_interface_or_router.config_params = params[1..-1]
|
|
176
|
+
@interfaces[interface_name] = current_interface_or_router
|
|
177
|
+
|
|
178
|
+
when 'LOG', 'LOG_STORED', 'DONT_LOG', 'TARGET'
|
|
179
|
+
raise parser.error("No current interface for #{keyword}") unless current_interface_or_router and current_type == :INTERFACE
|
|
180
|
+
|
|
181
|
+
case keyword
|
|
182
|
+
|
|
183
|
+
when 'LOG'
|
|
184
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Packet Log Writer Name>")
|
|
185
|
+
# packet_log_writer_pair = @packet_log_writer_pairs[params[0].upcase]
|
|
186
|
+
# raise parser.error("Unknown packet log writer: #{params[0].upcase}") unless packet_log_writer_pair
|
|
187
|
+
# current_interface_or_router.packet_log_writer_pairs.delete(@packet_log_writer_pairs['DEFAULT']) unless current_interface_log_added
|
|
188
|
+
current_interface_log_added = true
|
|
189
|
+
# current_interface_or_router.packet_log_writer_pairs << packet_log_writer_pair unless current_interface_or_router.packet_log_writer_pairs.include?(packet_log_writer_pair)
|
|
190
|
+
|
|
191
|
+
when 'LOG_STORED'
|
|
192
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Packet Log Writer Name>")
|
|
193
|
+
# packet_log_writer_pair = @packet_log_writer_pairs[params[0].upcase]
|
|
194
|
+
# raise parser.error("Unknown packet log writer: #{params[0].upcase}") unless packet_log_writer_pair
|
|
195
|
+
# current_interface_or_router.stored_packet_log_writer_pairs << packet_log_writer_pair unless current_interface_or_router.stored_packet_log_writer_pairs.include?(packet_log_writer_pair)
|
|
196
|
+
|
|
197
|
+
when 'DONT_LOG'
|
|
198
|
+
parser.verify_num_parameters(0, 0, "#{keyword}")
|
|
199
|
+
# current_interface_or_router.packet_log_writer_pairs = []
|
|
200
|
+
|
|
201
|
+
when 'TARGET'
|
|
202
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Target Name>")
|
|
203
|
+
target_name = params[0].upcase
|
|
204
|
+
target = @system_config.targets[target_name]
|
|
205
|
+
if target
|
|
206
|
+
interface_name = get_target_interface_name(target.name)
|
|
207
|
+
raise parser.error("Target #{target.name} already mapped to interface #{interface_name}") if interface_name
|
|
208
|
+
|
|
209
|
+
target.interface = current_interface_or_router
|
|
210
|
+
current_interface_or_router.target_names << target_name
|
|
211
|
+
else
|
|
212
|
+
raise parser.error("Unknown target #{target_name} mapped to interface #{current_interface_or_router.name}")
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
end # end case keyword for all keywords that require a current interface
|
|
216
|
+
|
|
217
|
+
when 'DONT_CONNECT', 'DONT_RECONNECT', 'RECONNECT_DELAY', 'DISABLE_DISCONNECT', 'LOG_RAW', 'OPTION', 'PROTOCOL'
|
|
218
|
+
raise parser.error("No current interface or router for #{keyword}") unless current_interface_or_router
|
|
219
|
+
|
|
220
|
+
case keyword
|
|
221
|
+
|
|
222
|
+
when 'DONT_CONNECT'
|
|
223
|
+
parser.verify_num_parameters(0, 0, "#{keyword}")
|
|
224
|
+
current_interface_or_router.connect_on_startup = false
|
|
225
|
+
|
|
226
|
+
when 'DONT_RECONNECT'
|
|
227
|
+
parser.verify_num_parameters(0, 0, "#{keyword}")
|
|
228
|
+
current_interface_or_router.auto_reconnect = false
|
|
229
|
+
|
|
230
|
+
when 'RECONNECT_DELAY'
|
|
231
|
+
parser.verify_num_parameters(1, 1, "#{keyword} <Delay in Seconds>")
|
|
232
|
+
current_interface_or_router.reconnect_delay = Float(params[0])
|
|
233
|
+
|
|
234
|
+
when 'DISABLE_DISCONNECT'
|
|
235
|
+
parser.verify_num_parameters(0, 0, "#{keyword}")
|
|
236
|
+
current_interface_or_router.disable_disconnect = true
|
|
237
|
+
|
|
238
|
+
when 'LOG_RAW',
|
|
239
|
+
parser.verify_num_parameters(0, nil, "#{keyword} <Raw Logger Class File (optional)> <Raw Logger Parameters (optional)>")
|
|
240
|
+
# current_interface_or_router.raw_logger_pair = RawLoggerPair.new(current_interface_or_router.name, params)
|
|
241
|
+
# current_interface_or_router.start_raw_logging
|
|
242
|
+
|
|
243
|
+
when 'OPTION'
|
|
244
|
+
parser.verify_num_parameters(2, nil, "#{keyword} <Option Name> <Option Value 1> <Option Value 2 (optional)> <etc>")
|
|
245
|
+
# current_interface_or_router.set_option(params[0], params[1..-1])
|
|
246
|
+
|
|
247
|
+
when 'PROTOCOL'
|
|
248
|
+
usage = "#{keyword} <READ WRITE READ_WRITE> <protocol filename or classname> <Protocol specific parameters>"
|
|
249
|
+
parser.verify_num_parameters(2, nil, usage)
|
|
250
|
+
unless %w(READ WRITE READ_WRITE).include? params[0].upcase
|
|
251
|
+
raise parser.error("Invalid protocol type: #{params[0]}", usage)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
begin
|
|
255
|
+
# klass = OpenC3.require_class(params[1])
|
|
256
|
+
# current_interface_or_router.add_protocol(klass, params[2..-1], params[0].upcase.intern)
|
|
257
|
+
rescue LoadError, StandardError => error
|
|
258
|
+
raise parser.error(error.message, usage)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
end # end case keyword for all keywords that require a current interface or router
|
|
262
|
+
|
|
263
|
+
when 'ROUTER'
|
|
264
|
+
usage = "ROUTER <Name> <Filename> <Specific Parameters>"
|
|
265
|
+
parser.verify_num_parameters(2, nil, usage)
|
|
266
|
+
router_name = params[0].upcase
|
|
267
|
+
raise parser.error("Router '#{router_name}' defined twice") if @routers[router_name]
|
|
268
|
+
|
|
269
|
+
# router_class = OpenC3.require_class(params[1])
|
|
270
|
+
# if params[2]
|
|
271
|
+
# current_interface_or_router = router_class.new(*params[2..-1])
|
|
272
|
+
# else
|
|
273
|
+
# current_interface_or_router = router_class.new
|
|
274
|
+
# end
|
|
275
|
+
current_interface_or_router = setup_interface_or_router()
|
|
276
|
+
current_type = :ROUTER
|
|
277
|
+
current_interface_or_router.name = router_name
|
|
278
|
+
@routers[router_name] = current_interface_or_router
|
|
279
|
+
|
|
280
|
+
when 'ROUTE'
|
|
281
|
+
raise parser.error("No current router for #{keyword}") unless current_interface_or_router and current_type == :ROUTER
|
|
282
|
+
|
|
283
|
+
usage = "ROUTE <Interface Name>"
|
|
284
|
+
parser.verify_num_parameters(1, 1, usage)
|
|
285
|
+
interface_name = params[0].upcase
|
|
286
|
+
interface = @interfaces[interface_name]
|
|
287
|
+
raise parser.error("Unknown interface #{interface_name} mapped to router #{current_interface_or_router.name}") unless interface
|
|
288
|
+
|
|
289
|
+
unless current_interface_or_router.interfaces.include? interface
|
|
290
|
+
current_interface_or_router.interfaces << interface
|
|
291
|
+
interface.routers << current_interface_or_router
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
when 'BACKGROUND_TASK'
|
|
295
|
+
usage = "#{keyword} <Filename> <Specific Parameters>"
|
|
296
|
+
parser.verify_num_parameters(1, nil, usage)
|
|
297
|
+
# background_task = OpenC3.require_class(params[0])
|
|
298
|
+
if params[1]
|
|
299
|
+
@background_tasks << params
|
|
300
|
+
else
|
|
301
|
+
@background_tasks << params
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
when 'STOPPED'
|
|
305
|
+
parser.verify_num_parameters(0, 0, "#{keyword}")
|
|
306
|
+
raise parser.error("No BACKGROUND_TASK defined") if @background_tasks.empty?
|
|
307
|
+
# @background_tasks[-1].stopped = true
|
|
308
|
+
|
|
309
|
+
when 'COLLECT_METADATA'
|
|
310
|
+
parser.verify_num_parameters(0, 0, "#{keyword}")
|
|
311
|
+
@metadata = true
|
|
312
|
+
|
|
313
|
+
else
|
|
314
|
+
# blank lines will have a nil keyword and should not raise an exception
|
|
315
|
+
raise parser.error("Unknown keyword: #{keyword}") unless keyword.nil?
|
|
316
|
+
end # case
|
|
317
|
+
end # loop
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2022 Ball Aerospace & Technologies Corp.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
|
7
|
+
# under the terms of the GNU Affero General Public License
|
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# Modified by OpenC3, Inc.
|
|
17
|
+
# All changes Copyright 2022, OpenC3, Inc.
|
|
18
|
+
# All Rights Reserved
|
|
19
|
+
|
|
20
|
+
module OpenC3
|
|
21
|
+
# Encapsulates an {Interface} in a Ruby thread. When the thread is started by
|
|
22
|
+
# the {#start} method, it loops trying to connect. It then continously reads
|
|
23
|
+
# from the interface while handling the packets it receives.
|
|
24
|
+
class InterfaceThread
|
|
25
|
+
# The number of bytes to print when an UNKNOWN packet is received
|
|
26
|
+
UNKNOWN_BYTES_TO_PRINT = 36
|
|
27
|
+
|
|
28
|
+
# @return [#call()] Callback which is called if the #{Interface#connect}
|
|
29
|
+
# method succeeds
|
|
30
|
+
attr_accessor :connection_success_callback
|
|
31
|
+
# @return [#call(Exception)] Callback which is called if the
|
|
32
|
+
# {Interface#connect} method throws an exception.
|
|
33
|
+
attr_accessor :connection_failed_callback
|
|
34
|
+
# @return [#call(Exception|nil)] Callback which is called if the
|
|
35
|
+
# interface connection is lost.
|
|
36
|
+
attr_accessor :connection_lost_callback
|
|
37
|
+
# @return [#call(Packet)] Callback which is called when a packet has been
|
|
38
|
+
# received from the interface and identified.
|
|
39
|
+
attr_accessor :identified_packet_callback
|
|
40
|
+
# @return [#call(Exception)] Callback which is called if the
|
|
41
|
+
# InterfaceThread dies for any reason.
|
|
42
|
+
attr_accessor :fatal_exception_callback
|
|
43
|
+
|
|
44
|
+
# @param interface [Interface] The interface to create a thread for
|
|
45
|
+
def initialize(interface)
|
|
46
|
+
@interface = interface
|
|
47
|
+
@connection_success_callback = nil
|
|
48
|
+
@connection_failed_callback = nil
|
|
49
|
+
@connection_lost_callback = nil
|
|
50
|
+
@identified_packet_callback = nil
|
|
51
|
+
@fatal_exception_callback = nil
|
|
52
|
+
@thread = nil
|
|
53
|
+
@thread_sleeper = Sleeper.new
|
|
54
|
+
@connection_failed_messages = []
|
|
55
|
+
@connection_lost_messages = []
|
|
56
|
+
@mutex = Mutex.new
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Create and start the Ruby thread that will encapsulate the interface.
|
|
60
|
+
# Creates a while loop that waits for {Interface#connect} to succeed. Then
|
|
61
|
+
# calls {Interface#read} and handles all the incoming packets.
|
|
62
|
+
def start
|
|
63
|
+
@thread_sleeper = Sleeper.new
|
|
64
|
+
@thread = Thread.new do
|
|
65
|
+
@cancel_thread = false
|
|
66
|
+
begin
|
|
67
|
+
if @interface.read_allowed?
|
|
68
|
+
Logger.info "Starting packet reading for #{@interface.name}"
|
|
69
|
+
else
|
|
70
|
+
Logger.info "Starting connection maintenance for #{@interface.name}"
|
|
71
|
+
end
|
|
72
|
+
while true
|
|
73
|
+
break if @cancel_thread
|
|
74
|
+
|
|
75
|
+
unless @interface.connected?
|
|
76
|
+
begin
|
|
77
|
+
@mutex.synchronize do
|
|
78
|
+
# We need to make sure connect is not called after stop() has been called
|
|
79
|
+
connect() unless @cancel_thread
|
|
80
|
+
end
|
|
81
|
+
break if @cancel_thread
|
|
82
|
+
rescue Exception => connect_error
|
|
83
|
+
handle_connection_failed(connect_error)
|
|
84
|
+
if @cancel_thread
|
|
85
|
+
break
|
|
86
|
+
else
|
|
87
|
+
next
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if @interface.read_allowed?
|
|
93
|
+
begin
|
|
94
|
+
packet = @interface.read
|
|
95
|
+
unless packet
|
|
96
|
+
Logger.info "Clean disconnect from #{@interface.name} (returned nil)"
|
|
97
|
+
handle_connection_lost(nil)
|
|
98
|
+
if @cancel_thread
|
|
99
|
+
break
|
|
100
|
+
else
|
|
101
|
+
next
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
packet.received_time = Time.now.sys unless packet.received_time
|
|
105
|
+
rescue Exception => err
|
|
106
|
+
handle_connection_lost(err)
|
|
107
|
+
if @cancel_thread
|
|
108
|
+
break
|
|
109
|
+
else
|
|
110
|
+
next
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
handle_packet(packet)
|
|
115
|
+
else
|
|
116
|
+
@thread_sleeper.sleep(1)
|
|
117
|
+
handle_connection_lost(nil) if !@interface.connected?
|
|
118
|
+
end
|
|
119
|
+
end # loop
|
|
120
|
+
rescue Exception => error
|
|
121
|
+
if @fatal_exception_callback
|
|
122
|
+
@fatal_exception_callback.call(error)
|
|
123
|
+
else
|
|
124
|
+
Logger.error "Packet reading thread unexpectedly died for #{@interface.name}"
|
|
125
|
+
OpenC3.handle_fatal_exception(error)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
Logger.info "Stopped packet reading for #{@interface.name}"
|
|
129
|
+
end # Thread.new
|
|
130
|
+
end # def start
|
|
131
|
+
|
|
132
|
+
# Disconnect from the interface and stop the thread
|
|
133
|
+
def stop
|
|
134
|
+
@mutex.synchronize do
|
|
135
|
+
# Need to make sure that @cancel_thread is set and the interface disconnected within
|
|
136
|
+
# mutex to ensure that connect() is not called when we want to stop()
|
|
137
|
+
@cancel_thread = true
|
|
138
|
+
@thread_sleeper.cancel
|
|
139
|
+
@interface.disconnect
|
|
140
|
+
end
|
|
141
|
+
OpenC3.kill_thread(self, @thread) if @thread and @thread != Thread.current
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def graceful_kill
|
|
145
|
+
# Just to avoid warning
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
protected
|
|
149
|
+
|
|
150
|
+
def handle_packet(packet)
|
|
151
|
+
if packet.stored
|
|
152
|
+
# Stored telemetry does not update the current value table
|
|
153
|
+
identified_packet = System.telemetry.identify_and_define_packet(packet, @interface.target_names)
|
|
154
|
+
else
|
|
155
|
+
# Identify and update packet
|
|
156
|
+
if packet.identified?
|
|
157
|
+
begin
|
|
158
|
+
# Preidentifed packet - place it into the current value table
|
|
159
|
+
identified_packet = System.telemetry.update!(packet.target_name,
|
|
160
|
+
packet.packet_name,
|
|
161
|
+
packet.buffer)
|
|
162
|
+
rescue RuntimeError
|
|
163
|
+
# Packet identified but we don't know about it
|
|
164
|
+
# Clear packet_name and target_name and try to identify
|
|
165
|
+
Logger.warn "Received unknown identified telemetry: #{packet.target_name} #{packet.packet_name}"
|
|
166
|
+
packet.target_name = nil
|
|
167
|
+
packet.packet_name = nil
|
|
168
|
+
identified_packet = System.telemetry.identify!(packet.buffer,
|
|
169
|
+
@interface.target_names)
|
|
170
|
+
end
|
|
171
|
+
else
|
|
172
|
+
# Packet needs to be identified
|
|
173
|
+
identified_packet = System.telemetry.identify!(packet.buffer,
|
|
174
|
+
@interface.target_names)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
if identified_packet
|
|
179
|
+
identified_packet.received_time = packet.received_time
|
|
180
|
+
identified_packet.stored = packet.stored
|
|
181
|
+
identified_packet.extra = packet.extra
|
|
182
|
+
packet = identified_packet
|
|
183
|
+
else
|
|
184
|
+
unknown_packet = System.telemetry.update!('UNKNOWN', 'UNKNOWN', packet.buffer)
|
|
185
|
+
unknown_packet.received_time = packet.received_time
|
|
186
|
+
unknown_packet.stored = packet.stored
|
|
187
|
+
unknown_packet.extra = packet.extra
|
|
188
|
+
packet = unknown_packet
|
|
189
|
+
data_length = packet.length
|
|
190
|
+
string = "#{@interface.name} - Unknown #{data_length} byte packet starting: "
|
|
191
|
+
num_bytes_to_print = [UNKNOWN_BYTES_TO_PRINT, data_length].min
|
|
192
|
+
data_to_print = packet.buffer(false)[0..(num_bytes_to_print - 1)]
|
|
193
|
+
data_to_print.each_byte do |byte|
|
|
194
|
+
string << sprintf("%02X", byte)
|
|
195
|
+
end
|
|
196
|
+
Logger.error string
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
target = System.targets[packet.target_name]
|
|
200
|
+
target.tlm_cnt += 1 if target
|
|
201
|
+
packet.received_count += 1
|
|
202
|
+
@identified_packet_callback.call(packet) if @identified_packet_callback
|
|
203
|
+
|
|
204
|
+
# Write to routers
|
|
205
|
+
@interface.routers.each do |router|
|
|
206
|
+
router.write(packet) if router.write_allowed? and router.connected?
|
|
207
|
+
rescue => err
|
|
208
|
+
Logger.error "Problem writing to router #{router.name} - #{err.class}:#{err.message}"
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Write to packet log writers
|
|
212
|
+
if packet.stored and !@interface.stored_packet_log_writer_pairs.empty?
|
|
213
|
+
@interface.stored_packet_log_writer_pairs.each do |packet_log_writer_pair|
|
|
214
|
+
packet_log_writer_pair.tlm_log_writer.write(packet)
|
|
215
|
+
end
|
|
216
|
+
else
|
|
217
|
+
@interface.packet_log_writer_pairs.each do |packet_log_writer_pair|
|
|
218
|
+
# Write errors are handled by the log writer
|
|
219
|
+
packet_log_writer_pair.tlm_log_writer.write(packet)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def handle_connection_failed(connect_error)
|
|
225
|
+
if @connection_failed_callback
|
|
226
|
+
@connection_failed_callback.call(connect_error)
|
|
227
|
+
else
|
|
228
|
+
Logger.error "#{@interface.name} Connection Failed: #{connect_error.formatted(false, false)}"
|
|
229
|
+
case connect_error
|
|
230
|
+
when Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ENOTSOCK, Errno::EHOSTUNREACH, IOError
|
|
231
|
+
# Do not write an exception file for these extremely common cases
|
|
232
|
+
else
|
|
233
|
+
if RuntimeError === connect_error and (connect_error.message =~ /canceled/ or connect_error.message =~ /timeout/)
|
|
234
|
+
# Do not write an exception file for these extremely common cases
|
|
235
|
+
else
|
|
236
|
+
Logger.error connect_error.formatted
|
|
237
|
+
unless @connection_failed_messages.include?(connect_error.message)
|
|
238
|
+
OpenC3.write_exception_file(connect_error)
|
|
239
|
+
@connection_failed_messages << connect_error.message
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
disconnect()
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def handle_connection_lost(err)
|
|
248
|
+
if @connection_lost_callback
|
|
249
|
+
@connection_lost_callback.call(err)
|
|
250
|
+
else
|
|
251
|
+
if err
|
|
252
|
+
Logger.info "Connection Lost for #{@interface.name}: #{err.formatted(false, false)}"
|
|
253
|
+
case err
|
|
254
|
+
when Errno::ECONNABORTED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EBADF, Errno::ENOTSOCK, IOError
|
|
255
|
+
# Do not write an exception file for these extremely common cases
|
|
256
|
+
else
|
|
257
|
+
Logger.error err.formatted
|
|
258
|
+
unless @connection_lost_messages.include?(err.message)
|
|
259
|
+
OpenC3.write_exception_file(err)
|
|
260
|
+
@connection_lost_messages << err.message
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
else
|
|
264
|
+
Logger.info "Connection Lost for #{@interface.name}"
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
disconnect()
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def connect
|
|
271
|
+
Logger.info "Connecting to #{@interface.name}..."
|
|
272
|
+
@interface.connect
|
|
273
|
+
if @connection_success_callback
|
|
274
|
+
@connection_success_callback.call
|
|
275
|
+
else
|
|
276
|
+
Logger.info "#{@interface.name} Connection Success"
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def disconnect
|
|
281
|
+
@interface.disconnect
|
|
282
|
+
|
|
283
|
+
# If the interface is set to auto_reconnect then delay so the thread
|
|
284
|
+
# can come back around and allow the interface a chance to reconnect.
|
|
285
|
+
if @interface.auto_reconnect
|
|
286
|
+
if !@cancel_thread
|
|
287
|
+
@thread_sleeper.sleep(@interface.reconnect_delay)
|
|
288
|
+
end
|
|
289
|
+
else
|
|
290
|
+
stop()
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end # class InterfaceThread
|
|
294
|
+
end
|