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.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. 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