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,498 @@
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'
21
+ require 'openc3/io/raw_logger_pair'
22
+
23
+ module OpenC3
24
+ # Defines all the attributes and methods common to all interface classes
25
+ # used by OpenC3.
26
+ class Interface
27
+ include Api
28
+
29
+ # @return [String] Name of the interface
30
+ attr_reader :name
31
+
32
+ # @return [String] State of the interface: CONNECTED, ATTEMPTING, DISCONNECTED
33
+ attr_accessor :state
34
+
35
+ # @return [Array<String>] Array of target names associated with this interface
36
+ attr_accessor :target_names
37
+
38
+ # @return [Boolean] Flag indicating if the interface should be connected
39
+ # to on startup
40
+ attr_accessor :connect_on_startup
41
+
42
+ # @return [Boolean] Flag indicating if the interface should automatically
43
+ # reconnect after losing connection
44
+ attr_accessor :auto_reconnect
45
+
46
+ # @return [Integer[ Delay between reconnect attempts
47
+ attr_accessor :reconnect_delay
48
+
49
+ # @return [Boolean] Flag indicating if the user is allowed to disconnect
50
+ # this interface
51
+ attr_accessor :disable_disconnect
52
+
53
+ # @return [Array] Array of packet logger classes for this interface
54
+ attr_accessor :packet_log_writer_pairs
55
+
56
+ # @return [Array] Array of stored packet log writers
57
+ attr_accessor :stored_packet_log_writer_pairs
58
+
59
+ # @return [RawLoggerPair] RawLoggerPair instance or nil
60
+ attr_accessor :raw_logger_pair
61
+
62
+ # @return [Array<Routers>] Array of routers that receive packets
63
+ # read from the interface
64
+ attr_accessor :routers
65
+
66
+ # @return [Array<Routers>] Array of cmd routers that mirror packets
67
+ # sent from the interface
68
+ attr_accessor :cmd_routers
69
+
70
+ # @return [Integer] The number of packets read from this interface
71
+ attr_accessor :read_count
72
+
73
+ # @return [Integer] The number of packets written to this interface
74
+ attr_accessor :write_count
75
+
76
+ # @return [Integer] The number of bytes read from this interface
77
+ attr_accessor :bytes_read
78
+
79
+ # @return [Integer] The number of bytes written to this interface
80
+ attr_accessor :bytes_written
81
+
82
+ # @return [Integer] The number of active clients
83
+ # (when used as a Router)
84
+ attr_accessor :num_clients
85
+
86
+ # @return [Integer] The number of packets in the read queue
87
+ # (when used as a Router)
88
+ attr_accessor :read_queue_size
89
+
90
+ # @return [Integer] The number of packets in the write queue
91
+ # (when used as a Router)
92
+ attr_accessor :write_queue_size
93
+
94
+ # @return [Hash<option name, option values>] Hash of options supplied to interface/router
95
+ attr_accessor :options
96
+
97
+ # @return [Array<Protocol>] Array of protocols for reading
98
+ attr_accessor :read_protocols
99
+
100
+ # @return [Array<Protocol>] Array of protocols for writing
101
+ attr_accessor :write_protocols
102
+
103
+ # @return [Array<[Protocol Class, Protocol Args, Protocol kind (:READ, :WRITE, :READ_WRITE)>] Info to recreate protocols
104
+ attr_accessor :protocol_info
105
+
106
+ # @return [Hash or nil] Hash of overridden telemetry points
107
+ attr_accessor :override_tlm
108
+
109
+ # @return [String] Most recently read raw data
110
+ attr_accessor :read_raw_data
111
+
112
+ # @return [String] Most recently written raw data
113
+ attr_accessor :written_raw_data
114
+
115
+ # @return [Time] Most recent read raw data time
116
+ attr_accessor :read_raw_data_time
117
+
118
+ # @return [Time] Most recent written raw data time
119
+ attr_accessor :written_raw_data_time
120
+
121
+ # @return [Array] Config params from the INTERFACE config line
122
+ attr_accessor :config_params
123
+
124
+ # @return [Array<Interface>] Array of interfaces to route packets to
125
+ # (when used as a BridgeRouter)
126
+ attr_accessor :interfaces
127
+
128
+ # Initialize default attribute values
129
+ def initialize
130
+ @name = self.class.to_s.split("::")[-1] # Remove namespacing if present
131
+ @state = 'DISCONNECTED'
132
+ @target_names = []
133
+ @connect_on_startup = true
134
+ @auto_reconnect = true
135
+ @reconnect_delay = 5.0
136
+ @disable_disconnect = false
137
+ @packet_log_writer_pairs = []
138
+ @stored_packet_log_writer_pairs = []
139
+ # TODO: How should this get the log directory
140
+ @raw_logger_pair = RawLoggerPair.new(@name, 'outputs/logs')
141
+ @routers = []
142
+ @cmd_routers = []
143
+ @read_count = 0
144
+ @write_count = 0
145
+ @bytes_read = 0
146
+ @bytes_written = 0
147
+ @num_clients = 0
148
+ @read_queue_size = 0
149
+ @write_queue_size = 0
150
+ @write_mutex = Mutex.new
151
+ @read_allowed = true
152
+ @write_allowed = true
153
+ @write_raw_allowed = true
154
+ @options = {}
155
+ @read_protocols = []
156
+ @write_protocols = []
157
+ @protocol_info = []
158
+ @override_tlm = nil
159
+ @read_raw_data = ''
160
+ @written_raw_data = ''
161
+ @read_raw_data_time = nil
162
+ @written_raw_data_time = nil
163
+ @config_params = []
164
+ @interfaces = []
165
+ end
166
+
167
+ # Connects the interface to its target(s). Must be implemented by a
168
+ # subclass.
169
+ def connect
170
+ (@read_protocols | @write_protocols).each { |protocol| protocol.connect_reset }
171
+ end
172
+
173
+ # Indicates if the interface is connected to its target(s) or not. Must be
174
+ # implemented by a subclass.
175
+ def connected?
176
+ raise "connected? not defined by Interface"
177
+ end
178
+
179
+ # Disconnects the interface from its target(s). Must be implemented by a
180
+ # subclass.
181
+ def disconnect
182
+ (@read_protocols | @write_protocols).each { |protocol| protocol.disconnect_reset }
183
+ end
184
+
185
+ def read_interface
186
+ raise "read_interface not defined by Interface"
187
+ end
188
+
189
+ def write_interface
190
+ raise "write_interface not defined by Interface"
191
+ end
192
+
193
+ # Retrieves the next packet from the interface.
194
+ # @return [Packet] Packet constructed from the data. Packet will be
195
+ # unidentified (nil target and packet names)
196
+ def read
197
+ raise "Interface not connected for read: #{@name}" unless connected?
198
+ raise "Interface not readable: #{@name}" unless read_allowed?
199
+
200
+ first = true
201
+ loop do
202
+ # Protocols may have cached data for a packet, so initially just inject a blank string
203
+ # Otherwise we can hold off outputing other packets where all the data has already
204
+ # been received
205
+ if !first or @read_protocols.length <= 0
206
+ # Read data for a packet
207
+ data = read_interface()
208
+ unless data
209
+ Logger.info("#{@name}: read_interface requested disconnect")
210
+ return nil
211
+ end
212
+ else
213
+ data = ''
214
+ first = false
215
+ end
216
+
217
+ @read_protocols.each do |protocol|
218
+ data = protocol.read_data(data)
219
+ if data == :DISCONNECT
220
+ Logger.info("#{@name}: Protocol #{protocol.class} read_data requested disconnect")
221
+ return nil
222
+ end
223
+ break if data == :STOP
224
+ end
225
+ next if data == :STOP
226
+
227
+ packet = convert_data_to_packet(data)
228
+
229
+ # Potentially modify packet
230
+ @read_protocols.each do |protocol|
231
+ packet = protocol.read_packet(packet)
232
+ if packet == :DISCONNECT
233
+ Logger.info("#{@name}: Protocol #{protocol.class} read_packet requested disconnect")
234
+ return nil
235
+ end
236
+ break if packet == :STOP
237
+ end
238
+ next if packet == :STOP
239
+
240
+ # Return packet
241
+ @read_count += 1
242
+ Logger.warn("#{@name}: Interface unexpectedly requested disconnect") unless packet
243
+ return packet
244
+ end
245
+ rescue Exception => err
246
+ Logger.error("#{@name}: Error reading from interface")
247
+ disconnect()
248
+ raise err
249
+ end
250
+
251
+ # Method to send a packet on the interface.
252
+ # @param packet [Packet] The Packet to send out the interface
253
+ def write(packet)
254
+ raise "Interface not connected for write: #{@name}" unless connected?
255
+ raise "Interface not writable: #{@name}" unless write_allowed?
256
+
257
+ _write do
258
+ @write_count += 1
259
+
260
+ # Potentially modify packet
261
+ @write_protocols.each do |protocol|
262
+ packet = protocol.write_packet(packet)
263
+ if packet == :DISCONNECT
264
+ Logger.info("#{@name}: Protocol #{protocol.class} write_packet requested disconnect")
265
+ disconnect()
266
+ return
267
+ end
268
+ return if packet == :STOP
269
+ end
270
+
271
+ data = convert_packet_to_data(packet)
272
+
273
+ # Potentially modify packet data
274
+ @write_protocols.each do |protocol|
275
+ data = protocol.write_data(data)
276
+ if data == :DISCONNECT
277
+ Logger.info("#{@name}: Protocol #{protocol.class} write_data requested disconnect")
278
+ disconnect()
279
+ return
280
+ end
281
+ return if data == :STOP
282
+ end
283
+
284
+ # Actually write out data if not handled by protocol
285
+ write_interface(data)
286
+
287
+ # Potentially block and wait for response
288
+ @write_protocols.each do |protocol|
289
+ packet, data = protocol.post_write_interface(packet, data)
290
+ if packet == :DISCONNECT
291
+ Logger.info("#{@name}: Protocol #{protocol.class} post_write_packet requested disconnect")
292
+ disconnect()
293
+ return
294
+ end
295
+ return if packet == :STOP
296
+ end
297
+ end
298
+
299
+ return nil
300
+ end
301
+
302
+ # Writes preformatted data onto the interface. Malformed data may cause
303
+ # problems.
304
+ # @param data [String] The raw data to send out the interface
305
+ def write_raw(data)
306
+ raise "Interface not connected for write_raw: #{@name}" unless connected?
307
+ raise "Interface not write-rawable: #{@name}" unless write_raw_allowed?
308
+
309
+ _write do
310
+ write_interface(data)
311
+ end
312
+ end
313
+
314
+ # Wrap all writes in a mutex and handle errors
315
+ def _write
316
+ if @write_mutex.owned?
317
+ yield
318
+ else
319
+ @write_mutex.synchronize { yield }
320
+ end
321
+ rescue Exception => err
322
+ Logger.error("#{@name}: Error writing to interface")
323
+ disconnect()
324
+ raise err
325
+ end
326
+
327
+ def as_json(*a)
328
+ config = {}
329
+ config['name'] = @name
330
+ config['state'] = @state
331
+ config['clients'] = @num_clients
332
+ config['txsize'] = @write_queue_size
333
+ config['rxsize'] = @read_queue_size
334
+ config['txbytes'] = @bytes_written
335
+ config['rxbytes'] = @bytes_read
336
+ config['txcnt'] = @write_count
337
+ config['rxcnt'] = @read_count
338
+ config
339
+ end
340
+
341
+ # @return [Boolean] Whether reading is allowed
342
+ def read_allowed?
343
+ @read_allowed
344
+ end
345
+
346
+ # @return [Boolean] Whether writing is allowed
347
+ def write_allowed?
348
+ @write_allowed
349
+ end
350
+
351
+ # @return [Boolean] Whether writing raw data over the interface is allowed
352
+ def write_raw_allowed?
353
+ @write_raw_allowed
354
+ end
355
+
356
+ # Start raw logging for this interface
357
+ def start_raw_logging
358
+ @raw_logger_pair.start if @raw_logger_pair
359
+ end
360
+
361
+ # Stop raw logging for this interface
362
+ def stop_raw_logging
363
+ @raw_logger_pair.stop if @raw_logger_pair
364
+ end
365
+
366
+ # Set the interface name
367
+ def name=(name)
368
+ @name = name.to_s.clone
369
+ @raw_logger_pair.name = name if @raw_logger_pair
370
+ end
371
+
372
+ # Copy settings from this interface to another interface. All instance
373
+ # variables are copied except for num_clients, read_queue_size,
374
+ # and write_queue_size since these are all specific to the operation of the
375
+ # interface rather than its instantiation.
376
+ #
377
+ # @param other_interface [Interface] The other interface to copy to
378
+ def copy_to(other_interface)
379
+ other_interface.name = self.name.clone
380
+ other_interface.target_names = self.target_names.clone
381
+ other_interface.connect_on_startup = self.connect_on_startup
382
+ other_interface.auto_reconnect = self.auto_reconnect
383
+ other_interface.reconnect_delay = self.reconnect_delay
384
+ other_interface.disable_disconnect = self.disable_disconnect
385
+ other_interface.packet_log_writer_pairs = self.packet_log_writer_pairs.clone
386
+ other_interface.routers = self.routers.clone
387
+ other_interface.cmd_routers = self.cmd_routers.clone
388
+ other_interface.read_count = self.read_count
389
+ other_interface.write_count = self.write_count
390
+ other_interface.bytes_read = self.bytes_read
391
+ other_interface.bytes_written = self.bytes_written
392
+ other_interface.raw_logger_pair = self.raw_logger_pair.clone if @raw_logger_pair
393
+ # num_clients is per interface so don't copy
394
+ # read_queue_size is the number of packets in the queue so don't copy
395
+ # write_queue_size is the number of packets in the queue so don't copy
396
+ other_interface.options = self.options.clone
397
+ other_interface.protocol_info = []
398
+ self.protocol_info.each do |protocol_class, protocol_args, read_write|
399
+ other_interface.add_protocol(protocol_class, protocol_args, read_write)
400
+ end
401
+ other_interface.override_tlm = nil
402
+ other_interface.override_tlm = self.override_tlm.clone if self.override_tlm
403
+ end
404
+
405
+ # Set an interface or router specific option
406
+ # @param option_name name of the option
407
+ # @param option_values array of option values
408
+ def set_option(option_name, option_values)
409
+ @options[option_name.upcase] = option_values.clone
410
+ end
411
+
412
+ # Called to convert the read data into a OpenC3 Packet object
413
+ #
414
+ # @param data [String] Raw packet data
415
+ # @return [Packet] OpenC3 Packet with buffer filled with data
416
+ def convert_data_to_packet(data)
417
+ Packet.new(nil, nil, :BIG_ENDIAN, nil, data)
418
+ end
419
+
420
+ # Called to convert a packet into the data to send
421
+ #
422
+ # @param packet [Packet] Packet to extract data from
423
+ # @return data
424
+ def convert_packet_to_data(packet)
425
+ packet.buffer(true) # Copy buffer so logged command isn't modified
426
+ end
427
+
428
+ # Called to read data and manipulate it until enough data is
429
+ # returned. The definition of 'enough data' changes depending on the
430
+ # protocol used which is why this method exists. This method is also used
431
+ # to perform operations on the data before it can be interpreted as packet
432
+ # data such as decryption. After this method is called the post_read_data
433
+ # method is called. Subclasses must implement this method.
434
+ #
435
+ # @return [String] Raw packet data
436
+ def read_interface_base(data)
437
+ @read_raw_data_time = Time.now
438
+ @read_raw_data = data.clone
439
+ @bytes_read += data.length
440
+ @raw_logger_pair.read_logger.write(data) if @raw_logger_pair
441
+ end
442
+
443
+ # Called to write data to the underlying interface. Subclasses must
444
+ # implement this method and call super to count the raw bytes and allow raw
445
+ # logging.
446
+ #
447
+ # @param data [String] Raw packet data
448
+ # @return [String] The exact data written
449
+ def write_interface_base(data)
450
+ @written_raw_data_time = Time.now
451
+ @written_raw_data = data.clone
452
+ @bytes_written += data.length
453
+ @raw_logger_pair.write_logger.write(data) if @raw_logger_pair
454
+ end
455
+
456
+ def add_protocol(protocol_class, protocol_args, read_write)
457
+ protocol_args = protocol_args.clone
458
+ protocol = protocol_class.new(*protocol_args)
459
+ case read_write
460
+ when :READ
461
+ @read_protocols << protocol
462
+ when :WRITE
463
+ @write_protocols.unshift(protocol)
464
+ when :READ_WRITE
465
+ @read_protocols << protocol
466
+ @write_protocols.unshift(protocol)
467
+ else
468
+ raise "Unknown protocol descriptor: #{read_write}. Must be :READ, :WRITE, or :READ_WRITE."
469
+ end
470
+ @protocol_info << [protocol_class, protocol_args, read_write]
471
+ protocol.interface = self
472
+ end
473
+
474
+ def _override_tlm(target_name, packet_name, item_name, value)
475
+ _override(target_name, packet_name, item_name, value, :CONVERTED)
476
+ end
477
+
478
+ def _override_tlm_raw(target_name, packet_name, item_name, value)
479
+ _override(target_name, packet_name, item_name, value, :RAW)
480
+ end
481
+
482
+ def _normalize_tlm(target_name, packet_name, item_name)
483
+ @override_tlm ||= {}
484
+ pkt = @override_tlm[target_name]
485
+ if pkt
486
+ items = @override_tlm[target_name][packet_name]
487
+ items.delete(item_name) if items
488
+ end
489
+ end
490
+
491
+ def _override(target_name, packet_name, item_name, value, type)
492
+ @override_tlm ||= {}
493
+ @override_tlm[target_name] ||= {}
494
+ @override_tlm[target_name][packet_name] ||= {}
495
+ @override_tlm[target_name][packet_name][item_name] = [value, type]
496
+ end
497
+ end
498
+ end