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,116 @@
|
|
|
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 'socket'
|
|
21
|
+
require 'thread' # For Mutex
|
|
22
|
+
require 'timeout' # For Timeout::Error
|
|
23
|
+
require 'openc3/streams/tcpip_socket_stream'
|
|
24
|
+
require 'openc3/config/config_parser'
|
|
25
|
+
|
|
26
|
+
module OpenC3
|
|
27
|
+
# Data {Stream} which reads and writes to TCPIP sockets. This class creates
|
|
28
|
+
# the actual sockets based on the constructor parameters. The rest of the
|
|
29
|
+
# interface is implemented by the super class {TcpipSocketStream}.
|
|
30
|
+
class TcpipClientStream < TcpipSocketStream
|
|
31
|
+
# @param hostname [String] The host to connect to
|
|
32
|
+
# @param write_port [Integer|nil] The port to write. Pass nil to make this
|
|
33
|
+
# a read only stream.
|
|
34
|
+
# @param read_port [Integer|nil] The port to read. Pass nil to make this
|
|
35
|
+
# a write only stream.
|
|
36
|
+
# @param write_timeout (see TcpipSocketStream#initialize)
|
|
37
|
+
# @param read_timeout (see TcpipSocketStream#initialize)
|
|
38
|
+
def initialize(hostname, write_port, read_port, write_timeout, read_timeout, connect_timeout = 5.0)
|
|
39
|
+
@hostname = hostname
|
|
40
|
+
if @hostname.to_s.upcase == 'LOCALHOST'
|
|
41
|
+
@hostname = '127.0.0.1'
|
|
42
|
+
end
|
|
43
|
+
@write_port = ConfigParser.handle_nil(write_port)
|
|
44
|
+
@write_port = Integer(write_port) if @write_port
|
|
45
|
+
@read_port = ConfigParser.handle_nil(read_port)
|
|
46
|
+
@read_port = Integer(read_port) if @read_port
|
|
47
|
+
|
|
48
|
+
@write_addr = nil
|
|
49
|
+
@read_addr = nil
|
|
50
|
+
begin
|
|
51
|
+
@write_addr = Socket.pack_sockaddr_in(@write_port, @hostname) if @write_port
|
|
52
|
+
@read_addr = Socket.pack_sockaddr_in(@read_port, @hostname) if @read_port
|
|
53
|
+
rescue => error
|
|
54
|
+
if /getaddrinfo/.match?(error.message)
|
|
55
|
+
raise "Invalid hostname: #{@hostname}"
|
|
56
|
+
else
|
|
57
|
+
raise error
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
write_socket = nil
|
|
62
|
+
if @write_addr
|
|
63
|
+
write_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
|
64
|
+
write_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
read_socket = nil
|
|
68
|
+
if @read_addr
|
|
69
|
+
if @write_port != @read_port
|
|
70
|
+
read_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
|
71
|
+
read_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
72
|
+
else
|
|
73
|
+
read_socket = write_socket
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
@connect_timeout = ConfigParser.handle_nil(connect_timeout)
|
|
78
|
+
@connect_timeout = @connect_timeout.to_f if @connect_timeout
|
|
79
|
+
|
|
80
|
+
super(write_socket, read_socket, write_timeout, read_timeout)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Connect the socket(s)
|
|
84
|
+
def connect
|
|
85
|
+
connect_nonblock(@write_socket, @write_addr) if @write_socket
|
|
86
|
+
connect_nonblock(@read_socket, @read_addr) if @read_socket and @read_socket != @write_socket
|
|
87
|
+
super()
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
protected
|
|
91
|
+
|
|
92
|
+
def connect_nonblock(socket, addr)
|
|
93
|
+
socket.connect_nonblock(addr)
|
|
94
|
+
rescue IO::WaitWritable
|
|
95
|
+
begin
|
|
96
|
+
_, sockets, _ = IO.select(nil, [socket], nil, @connect_timeout) # wait 3-way handshake completion
|
|
97
|
+
rescue IOError, Errno::ENOTSOCK
|
|
98
|
+
raise "Connect canceled"
|
|
99
|
+
end
|
|
100
|
+
if sockets and !sockets.empty?
|
|
101
|
+
begin
|
|
102
|
+
socket.connect_nonblock(addr) # check connection failure
|
|
103
|
+
rescue IOError, Errno::ENOTSOCK
|
|
104
|
+
raise "Connect canceled"
|
|
105
|
+
rescue Errno::EINPROGRESS
|
|
106
|
+
retry
|
|
107
|
+
rescue Errno::EISCONN, Errno::EALREADY
|
|
108
|
+
end
|
|
109
|
+
else
|
|
110
|
+
raise "Connect timeout"
|
|
111
|
+
end
|
|
112
|
+
rescue IOError, Errno::ENOTSOCK
|
|
113
|
+
raise "Connect canceled"
|
|
114
|
+
end
|
|
115
|
+
end # class TcpipClientStream
|
|
116
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
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 'socket'
|
|
21
|
+
require 'thread' # For Mutex
|
|
22
|
+
require 'timeout' # For Timeout::Error
|
|
23
|
+
require 'openc3/streams/stream'
|
|
24
|
+
require 'openc3/config/config_parser'
|
|
25
|
+
|
|
26
|
+
module OpenC3
|
|
27
|
+
# Data {Stream} which reads and writes from Tcpip Sockets.
|
|
28
|
+
class TcpipSocketStream < Stream
|
|
29
|
+
attr_reader :write_socket
|
|
30
|
+
|
|
31
|
+
FAST_READ = (RUBY_VERSION > "2.1")
|
|
32
|
+
|
|
33
|
+
# @param write_socket [Socket] Socket to write
|
|
34
|
+
# @param read_socket [Socket] Socket to read
|
|
35
|
+
# @param write_timeout [Float|nil] Number of seconds to wait for the write
|
|
36
|
+
# to complete or nil to block until the socket is ready to write.
|
|
37
|
+
# @param read_timeout [Float|nil] Number of seconds to wait for the read
|
|
38
|
+
# to complete or nil to block until the socket is ready to read.
|
|
39
|
+
def initialize(write_socket, read_socket, write_timeout, read_timeout)
|
|
40
|
+
super()
|
|
41
|
+
|
|
42
|
+
@write_socket = write_socket
|
|
43
|
+
@read_socket = read_socket
|
|
44
|
+
@write_timeout = ConfigParser.handle_nil(write_timeout)
|
|
45
|
+
@write_timeout = @write_timeout.to_f if @write_timeout
|
|
46
|
+
@read_timeout = ConfigParser.handle_nil(read_timeout)
|
|
47
|
+
@read_timeout = @read_timeout.to_f if @read_timeout
|
|
48
|
+
|
|
49
|
+
# Mutex on write is needed to protect from commands coming in from more
|
|
50
|
+
# than one tool
|
|
51
|
+
@write_mutex = Mutex.new
|
|
52
|
+
@pipe_reader, @pipe_writer = IO.pipe
|
|
53
|
+
@connected = false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [String] Returns a binary string of data from the socket
|
|
57
|
+
def read
|
|
58
|
+
raise "Attempt to read from write only stream" unless @read_socket
|
|
59
|
+
|
|
60
|
+
# No read mutex is needed because reads happen serially
|
|
61
|
+
if FAST_READ
|
|
62
|
+
begin
|
|
63
|
+
while true # Loop until we get some data
|
|
64
|
+
data = @read_socket.read_nonblock(65535, exception: false)
|
|
65
|
+
raise EOFError, 'end of file reached' unless data
|
|
66
|
+
|
|
67
|
+
if data == :wait_readable
|
|
68
|
+
# Wait for the socket to be ready for reading or for the timeout
|
|
69
|
+
begin
|
|
70
|
+
result = IO.fast_select([@read_socket, @pipe_reader], nil, nil, @read_timeout)
|
|
71
|
+
# If select returns something it means the socket is now available for
|
|
72
|
+
# reading so retry the read. If it returns nil it means we timed out.
|
|
73
|
+
# If the pipe is present that means we closed the socket
|
|
74
|
+
if result
|
|
75
|
+
if result.include?(@pipe_reader)
|
|
76
|
+
raise IOError
|
|
77
|
+
else
|
|
78
|
+
next
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
raise Timeout::Error, "Read Timeout"
|
|
82
|
+
end
|
|
83
|
+
rescue IOError, Errno::ENOTSOCK
|
|
84
|
+
# These can happen with the socket being closed while waiting on select
|
|
85
|
+
data = ''
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
break
|
|
89
|
+
end
|
|
90
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError, Errno::ENOTSOCK
|
|
91
|
+
data = ''
|
|
92
|
+
end
|
|
93
|
+
else
|
|
94
|
+
begin
|
|
95
|
+
data = @read_socket.read_nonblock(65535)
|
|
96
|
+
rescue IO::WaitReadable
|
|
97
|
+
# Wait for the socket to be ready for reading or for the timeout
|
|
98
|
+
begin
|
|
99
|
+
result = IO.fast_select([@read_socket, @pipe_reader], nil, nil, @read_timeout)
|
|
100
|
+
|
|
101
|
+
# If select returns something it means the socket is now available for
|
|
102
|
+
# reading so retry the read. If it returns nil it means we timed out.
|
|
103
|
+
# If the pipe is present that means we closed the socket
|
|
104
|
+
if result
|
|
105
|
+
if result.include?(@pipe_reader)
|
|
106
|
+
raise IOError
|
|
107
|
+
else
|
|
108
|
+
retry
|
|
109
|
+
end
|
|
110
|
+
else
|
|
111
|
+
raise Timeout::Error, "Read Timeout"
|
|
112
|
+
end
|
|
113
|
+
rescue IOError, Errno::ENOTSOCK
|
|
114
|
+
# These can happen with the socket being closed while waiting on select
|
|
115
|
+
data = ''
|
|
116
|
+
end
|
|
117
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError, Errno::ENOTSOCK
|
|
118
|
+
data = ''
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
data
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# @return [String] Returns a binary string of data from the socket. Always returns immediately
|
|
126
|
+
def read_nonblock
|
|
127
|
+
# No read mutex is needed because reads happen serially
|
|
128
|
+
begin
|
|
129
|
+
if FAST_READ
|
|
130
|
+
data = @read_socket.read_nonblock(65535, exception: false)
|
|
131
|
+
raise EOFError, 'end of file reached' unless data
|
|
132
|
+
|
|
133
|
+
data = '' if data == :wait_readable
|
|
134
|
+
else
|
|
135
|
+
data = @read_socket.read_nonblock(65535)
|
|
136
|
+
end
|
|
137
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNRESET, Errno::ECONNABORTED, IOError
|
|
138
|
+
data = ''
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
data
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# @param data [String] A binary string of data to write to the socket
|
|
145
|
+
def write(data)
|
|
146
|
+
raise "Attempt to write to read only stream" unless @write_socket
|
|
147
|
+
|
|
148
|
+
@write_mutex.synchronize do
|
|
149
|
+
num_bytes_to_send = data.length
|
|
150
|
+
total_bytes_sent = 0
|
|
151
|
+
bytes_sent = 0
|
|
152
|
+
data_to_send = data
|
|
153
|
+
|
|
154
|
+
loop do
|
|
155
|
+
begin
|
|
156
|
+
bytes_sent = @write_socket.write_nonblock(data_to_send)
|
|
157
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
|
158
|
+
# Wait for the socket to be ready for writing or for the timeout
|
|
159
|
+
result = IO.fast_select(nil, [@write_socket], nil, @write_timeout)
|
|
160
|
+
# If select returns something it means the socket is now available for
|
|
161
|
+
# writing so retry the write. If it returns nil it means we timed out.
|
|
162
|
+
if result
|
|
163
|
+
retry
|
|
164
|
+
else
|
|
165
|
+
raise Timeout::Error, "Write Timeout"
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
total_bytes_sent += bytes_sent
|
|
169
|
+
break if total_bytes_sent >= num_bytes_to_send
|
|
170
|
+
|
|
171
|
+
data_to_send = data[total_bytes_sent..-1]
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Connect the stream
|
|
177
|
+
def connect
|
|
178
|
+
# If called directly this class is acting as a server and does not need to connect the sockets
|
|
179
|
+
@connected = true
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# @return [Boolean] Whether the sockets are connected
|
|
183
|
+
def connected?
|
|
184
|
+
@connected
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Disconnect by closing the sockets
|
|
188
|
+
def disconnect
|
|
189
|
+
OpenC3.close_socket(@write_socket)
|
|
190
|
+
OpenC3.close_socket(@read_socket)
|
|
191
|
+
@pipe_writer.write('.')
|
|
192
|
+
@connected = false
|
|
193
|
+
end
|
|
194
|
+
end # class TcpipSocketStream
|
|
195
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
require 'openc3/packets/packet_config'
|
|
22
|
+
require 'openc3/packets/commands'
|
|
23
|
+
# TODO: System requires telemetry and Telemetry require system ... circular reference
|
|
24
|
+
require 'openc3/packets/telemetry'
|
|
25
|
+
require 'openc3/packets/limits'
|
|
26
|
+
require 'openc3/system/target'
|
|
27
|
+
require 'openc3/utilities/s3'
|
|
28
|
+
require 'openc3/utilities/zip'
|
|
29
|
+
require 'openc3/models/scope_model'
|
|
30
|
+
require 'thread'
|
|
31
|
+
require 'fileutils'
|
|
32
|
+
|
|
33
|
+
module OpenC3
|
|
34
|
+
class System
|
|
35
|
+
# @return [Hash<String,Target>] Hash of all the known targets
|
|
36
|
+
instance_attr_reader :targets
|
|
37
|
+
|
|
38
|
+
# @return [PacketConfig] Access to the packet configuration
|
|
39
|
+
instance_attr_reader :packet_config
|
|
40
|
+
|
|
41
|
+
# @return [Commands] Access to the command definition
|
|
42
|
+
instance_attr_reader :commands
|
|
43
|
+
|
|
44
|
+
# @return [Telemetry] Access to the telemetry definition
|
|
45
|
+
instance_attr_reader :telemetry
|
|
46
|
+
|
|
47
|
+
# @return [Limits] Access to the limits definition
|
|
48
|
+
instance_attr_reader :limits
|
|
49
|
+
|
|
50
|
+
# Variable that holds the singleton instance
|
|
51
|
+
@@instance = nil
|
|
52
|
+
|
|
53
|
+
# Mutex used to ensure that only one instance of System is created
|
|
54
|
+
@@instance_mutex = Mutex.new
|
|
55
|
+
|
|
56
|
+
# @return [Symbol] The current limits_set of the system returned from Redis
|
|
57
|
+
def self.limits_set
|
|
58
|
+
ScopeModel.limits_set(scope: $openc3_scope)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.setup_targets(target_names, base_dir, scope:)
|
|
62
|
+
FileUtils.mkdir_p("#{base_dir}/targets")
|
|
63
|
+
rubys3_client = Aws::S3::Client.new
|
|
64
|
+
target_names.each do |target_name|
|
|
65
|
+
# Retrieve bucket/targets/target_name/target_id.zip
|
|
66
|
+
response_target = "#{base_dir}/targets/#{target_name}_current.zip"
|
|
67
|
+
FileUtils.mkdir_p(File.dirname(response_target))
|
|
68
|
+
s3_key = "#{scope}/target_archives/#{target_name}/#{target_name}_current.zip"
|
|
69
|
+
Logger.info("Retrieving #{s3_key} from targets bucket")
|
|
70
|
+
rubys3_client.get_object(bucket: "config", key: s3_key, response_target: response_target)
|
|
71
|
+
Zip::File.open(response_target) do |zip_file|
|
|
72
|
+
zip_file.each do |entry|
|
|
73
|
+
path = File.join("#{base_dir}/targets", entry.name)
|
|
74
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
75
|
+
zip_file.extract(entry, path) unless File.exist?(path)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Build System from targets
|
|
81
|
+
System.instance(target_names, "#{base_dir}/targets")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Get the singleton instance of System
|
|
85
|
+
#
|
|
86
|
+
# @param target_names [Array of target_names]
|
|
87
|
+
# @param target_config_dir Directory where target config folders are
|
|
88
|
+
# @return [System] The System singleton
|
|
89
|
+
def self.instance(target_names = nil, target_config_dir = nil)
|
|
90
|
+
return @@instance if @@instance
|
|
91
|
+
raise "System.instance parameters are required on first call" unless target_names and target_config_dir
|
|
92
|
+
|
|
93
|
+
@@instance_mutex.synchronize do
|
|
94
|
+
@@instance ||= self.new(target_names, target_config_dir)
|
|
95
|
+
return @@instance
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Create a new System object.
|
|
100
|
+
#
|
|
101
|
+
# @param target_names [Array of target names]
|
|
102
|
+
# @param target_config_dir Directory where target config folders are
|
|
103
|
+
def initialize(target_names, target_config_dir)
|
|
104
|
+
@targets = {}
|
|
105
|
+
@packet_config = PacketConfig.new
|
|
106
|
+
@commands = Commands.new(@packet_config)
|
|
107
|
+
@telemetry = Telemetry.new(@packet_config)
|
|
108
|
+
@limits = Limits.new(@packet_config)
|
|
109
|
+
target_names.each { |target_name| add_target(target_name, target_config_dir) }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def add_target(target_name, target_config_dir)
|
|
113
|
+
parser = ConfigParser.new
|
|
114
|
+
folder_name = File.join(target_config_dir, target_name)
|
|
115
|
+
raise parser.error("Target folder must exist '#{folder_name}'.") unless Dir.exist?(folder_name)
|
|
116
|
+
|
|
117
|
+
target = Target.new(target_name, target_config_dir)
|
|
118
|
+
@targets[target.name] = target
|
|
119
|
+
target.cmd_tlm_files.each do |cmd_tlm_file|
|
|
120
|
+
@packet_config.process_file(cmd_tlm_file, target.name)
|
|
121
|
+
rescue Exception => err
|
|
122
|
+
Logger.error "Problem processing #{cmd_tlm_file}: #{err}."
|
|
123
|
+
raise err
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|