openc3 5.0.6

Sign up to get free protection for your applications and to get access to all the features.
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,24 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ module OpenC3
21
+ autoload(:Target, "openc3/system/target.rb")
22
+ autoload(:System, "openc3/system/system.rb")
23
+ autoload(:SystemConfig, "openc3/system/system_config.rb")
24
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'openc3/api/api'
@@ -0,0 +1,320 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ require 'openc3/config/config_parser'
21
+
22
+ module OpenC3
23
+ # Reads an ascii file that defines the configuration settings used to
24
+ # configure the Command/Telemetry Server.
25
+ class CmdTlmServerConfig
26
+ # @return [Hash<String, Interface>] Interfaces hash
27
+ attr_accessor :interfaces
28
+ # @return [Hash<String, Interface>] Routers hash
29
+ attr_accessor :routers
30
+ # @return [Hash<String, PacketLogWriterPair>] Packet log writer hash. Each
31
+ # pair encapsulates a command and telemetry log writer.
32
+ attr_accessor :packet_log_writer_pairs
33
+ # @return [Array<BackgroundTask>] Array of background tasks
34
+ attr_accessor :background_tasks
35
+ # @return [String] Command and Telemetry Server title
36
+ attr_accessor :title
37
+ # @return [Boolean] Flag indicating if meta data should be collected
38
+ attr_accessor :metadata
39
+
40
+ # Create a default pair of packet log writers and parses the
41
+ # configuration file.
42
+ #
43
+ # @param filename [String] The name of the configuration file to parse
44
+ def initialize(filename, system_config)
45
+ @system_config = system_config
46
+ @interfaces = {}
47
+ @routers = {}
48
+ @packet_log_writer_pairs = {}
49
+ # cmd_log_writer = System.default_packet_log_writer.new(:CMD, *System.default_packet_log_writer_params)
50
+ # tlm_log_writer = System.default_packet_log_writer.new(:TLM, *System.default_packet_log_writer_params)
51
+ # @packet_log_writer_pairs['DEFAULT'] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
52
+ @background_tasks = []
53
+ @title = nil
54
+ @metadata = false
55
+ process_file(filename)
56
+ end
57
+
58
+ protected
59
+
60
+ def get_target_interface_name(target_name)
61
+ @interfaces.each do |interface_name, interface|
62
+ return interface_name if interface.target_names.include?(target_name)
63
+ end
64
+ nil
65
+ end
66
+
67
+ def setup_interface_or_router
68
+ current_interface_or_router = OpenStruct.new
69
+ current_interface_or_router.interfaces = []
70
+ current_interface_or_router.routers = []
71
+ current_interface_or_router.target_names = []
72
+ current_interface_or_router
73
+ end
74
+
75
+ # Processes a file and adds in the configuration defined in the file
76
+ #
77
+ # @param filename [String] The name of the configuration file to parse
78
+ # @param recursive [Boolean] Whether process_file is being called
79
+ # recursively
80
+ def process_file(filename, recursive = false)
81
+ current_interface_or_router = nil
82
+ current_type = nil
83
+ current_interface_log_added = false
84
+
85
+ Logger.info "Processing CmdTlmServer configuration in file: #{File.expand_path(filename)}"
86
+
87
+ parser = ConfigParser.new("https://openc3.com/docs/v5")
88
+ parser.parse_file(filename) do |keyword, params|
89
+ case keyword
90
+ when 'TITLE'
91
+ raise parser.error("#{keyword} not allowed in target #{filename}") if recursive
92
+
93
+ parser.verify_num_parameters(1, 1, "#{keyword} <Title Text>")
94
+ @title = params[0]
95
+
96
+ when 'PACKET_LOG_WRITER'
97
+ # usage = "PACKET_LOG_WRITER <Name> <Filename> <Specific Parameters>"
98
+ # parser.verify_num_parameters(2, nil, usage)
99
+ # packet_log_writer_name = params[0].upcase
100
+ # packet_log_writer_class = OpenC3.require_class(params[1])
101
+
102
+ # # Verify not overridding a packet log writer that is already associated with an interface
103
+ # packet_log_writer_pair = @packet_log_writer_pairs[packet_log_writer_name]
104
+ # if packet_log_writer_pair
105
+ # @interfaces.each do |interface_name, interface|
106
+ # if interface.packet_log_writer_pairs.include?(packet_log_writer_pair)
107
+ # raise parser.error("Redefining Packet Log Writer #{packet_log_writer_name} not allowed after it is associated with an interface")
108
+ # end
109
+ # end
110
+ # end
111
+
112
+ # if params[2]
113
+ # cmd_log_writer = packet_log_writer_class.new(:CMD, *params[2..-1])
114
+ # tlm_log_writer = packet_log_writer_class.new(:TLM, *params[2..-1])
115
+ # @packet_log_writer_pairs[packet_log_writer_name] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
116
+ # else
117
+ # cmd_log_writer = packet_log_writer_class.new(:CMD)
118
+ # tlm_log_writer = packet_log_writer_class.new(:TLM)
119
+ # @packet_log_writer_pairs[packet_log_writer_name] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
120
+ # end
121
+
122
+ when 'AUTO_INTERFACE_TARGETS'
123
+ raise parser.error("#{keyword} not allowed in target #{filename}") if recursive
124
+
125
+ usage = "#{keyword}"
126
+ parser.verify_num_parameters(0, 0, usage)
127
+ @system_config.targets.each do |target_name, target|
128
+ target_filename = File.join(target.dir, 'cmd_tlm_server.txt')
129
+ if File.exist?(target_filename)
130
+ # Skip this target if it's already been assigned an interface
131
+ next if get_target_interface_name(target.name)
132
+ raise parser.error("Cannot use #{keyword} with target name substitutions: #{target.name} != #{target.original_name}") if target.name != target.original_name
133
+
134
+ process_file(target_filename, true)
135
+ end
136
+ end
137
+
138
+ when 'INTERFACE_TARGET'
139
+ raise parser.error("#{keyword} not allowed in target #{filename}") if recursive
140
+
141
+ usage = "#{keyword} <Target Name> <Config File (defaults to cmd_tlm_server.txt)>"
142
+ parser.verify_num_parameters(1, 2, usage)
143
+ target = @system_config.targets[params[0].upcase]
144
+ raise parser.error("Unknown target: #{params[0].upcase}") unless target
145
+
146
+ interface_name = get_target_interface_name(target.name)
147
+ raise parser.error("Target #{target.name} already mapped to interface #{interface_name}") if interface_name
148
+
149
+ target_filename = params[1]
150
+ target_filename = 'cmd_tlm_server.txt' unless target_filename
151
+ target_filename = File.join(target.dir, target_filename)
152
+ if File.exist?(target_filename)
153
+ process_file(target_filename, true)
154
+ else
155
+ raise parser.error("#{target_filename} does not exist")
156
+ end
157
+
158
+ when 'INTERFACE'
159
+ usage = "INTERFACE <Name> <Filename> <Specific Parameters>"
160
+ parser.verify_num_parameters(2, nil, usage)
161
+ interface_name = params[0].upcase
162
+ raise parser.error("Interface '#{interface_name}' defined twice") if @interfaces[interface_name]
163
+
164
+ # interface_class = OpenC3.require_class(params[1])
165
+ # if params[2]
166
+ # current_interface_or_router = interface_class.new(*params[2..-1])
167
+ # else
168
+ # current_interface_or_router = interface_class.new
169
+ # end
170
+ current_interface_or_router = setup_interface_or_router()
171
+ current_type = :INTERFACE
172
+ current_interface_log_added = false
173
+ # current_interface_or_router.packet_log_writer_pairs << @packet_log_writer_pairs['DEFAULT']
174
+ current_interface_or_router.name = interface_name
175
+ current_interface_or_router.config_params = params[1..-1]
176
+ @interfaces[interface_name] = current_interface_or_router
177
+
178
+ when 'LOG', 'LOG_STORED', 'DONT_LOG', 'TARGET'
179
+ raise parser.error("No current interface for #{keyword}") unless current_interface_or_router and current_type == :INTERFACE
180
+
181
+ case keyword
182
+
183
+ when 'LOG'
184
+ parser.verify_num_parameters(1, 1, "#{keyword} <Packet Log Writer Name>")
185
+ # packet_log_writer_pair = @packet_log_writer_pairs[params[0].upcase]
186
+ # raise parser.error("Unknown packet log writer: #{params[0].upcase}") unless packet_log_writer_pair
187
+ # current_interface_or_router.packet_log_writer_pairs.delete(@packet_log_writer_pairs['DEFAULT']) unless current_interface_log_added
188
+ current_interface_log_added = true
189
+ # current_interface_or_router.packet_log_writer_pairs << packet_log_writer_pair unless current_interface_or_router.packet_log_writer_pairs.include?(packet_log_writer_pair)
190
+
191
+ when 'LOG_STORED'
192
+ parser.verify_num_parameters(1, 1, "#{keyword} <Packet Log Writer Name>")
193
+ # packet_log_writer_pair = @packet_log_writer_pairs[params[0].upcase]
194
+ # raise parser.error("Unknown packet log writer: #{params[0].upcase}") unless packet_log_writer_pair
195
+ # current_interface_or_router.stored_packet_log_writer_pairs << packet_log_writer_pair unless current_interface_or_router.stored_packet_log_writer_pairs.include?(packet_log_writer_pair)
196
+
197
+ when 'DONT_LOG'
198
+ parser.verify_num_parameters(0, 0, "#{keyword}")
199
+ # current_interface_or_router.packet_log_writer_pairs = []
200
+
201
+ when 'TARGET'
202
+ parser.verify_num_parameters(1, 1, "#{keyword} <Target Name>")
203
+ target_name = params[0].upcase
204
+ target = @system_config.targets[target_name]
205
+ if target
206
+ interface_name = get_target_interface_name(target.name)
207
+ raise parser.error("Target #{target.name} already mapped to interface #{interface_name}") if interface_name
208
+
209
+ target.interface = current_interface_or_router
210
+ current_interface_or_router.target_names << target_name
211
+ else
212
+ raise parser.error("Unknown target #{target_name} mapped to interface #{current_interface_or_router.name}")
213
+ end
214
+
215
+ end # end case keyword for all keywords that require a current interface
216
+
217
+ when 'DONT_CONNECT', 'DONT_RECONNECT', 'RECONNECT_DELAY', 'DISABLE_DISCONNECT', 'LOG_RAW', 'OPTION', 'PROTOCOL'
218
+ raise parser.error("No current interface or router for #{keyword}") unless current_interface_or_router
219
+
220
+ case keyword
221
+
222
+ when 'DONT_CONNECT'
223
+ parser.verify_num_parameters(0, 0, "#{keyword}")
224
+ current_interface_or_router.connect_on_startup = false
225
+
226
+ when 'DONT_RECONNECT'
227
+ parser.verify_num_parameters(0, 0, "#{keyword}")
228
+ current_interface_or_router.auto_reconnect = false
229
+
230
+ when 'RECONNECT_DELAY'
231
+ parser.verify_num_parameters(1, 1, "#{keyword} <Delay in Seconds>")
232
+ current_interface_or_router.reconnect_delay = Float(params[0])
233
+
234
+ when 'DISABLE_DISCONNECT'
235
+ parser.verify_num_parameters(0, 0, "#{keyword}")
236
+ current_interface_or_router.disable_disconnect = true
237
+
238
+ when 'LOG_RAW',
239
+ parser.verify_num_parameters(0, nil, "#{keyword} <Raw Logger Class File (optional)> <Raw Logger Parameters (optional)>")
240
+ # current_interface_or_router.raw_logger_pair = RawLoggerPair.new(current_interface_or_router.name, params)
241
+ # current_interface_or_router.start_raw_logging
242
+
243
+ when 'OPTION'
244
+ parser.verify_num_parameters(2, nil, "#{keyword} <Option Name> <Option Value 1> <Option Value 2 (optional)> <etc>")
245
+ # current_interface_or_router.set_option(params[0], params[1..-1])
246
+
247
+ when 'PROTOCOL'
248
+ usage = "#{keyword} <READ WRITE READ_WRITE> <protocol filename or classname> <Protocol specific parameters>"
249
+ parser.verify_num_parameters(2, nil, usage)
250
+ unless %w(READ WRITE READ_WRITE).include? params[0].upcase
251
+ raise parser.error("Invalid protocol type: #{params[0]}", usage)
252
+ end
253
+
254
+ begin
255
+ # klass = OpenC3.require_class(params[1])
256
+ # current_interface_or_router.add_protocol(klass, params[2..-1], params[0].upcase.intern)
257
+ rescue LoadError, StandardError => error
258
+ raise parser.error(error.message, usage)
259
+ end
260
+
261
+ end # end case keyword for all keywords that require a current interface or router
262
+
263
+ when 'ROUTER'
264
+ usage = "ROUTER <Name> <Filename> <Specific Parameters>"
265
+ parser.verify_num_parameters(2, nil, usage)
266
+ router_name = params[0].upcase
267
+ raise parser.error("Router '#{router_name}' defined twice") if @routers[router_name]
268
+
269
+ # router_class = OpenC3.require_class(params[1])
270
+ # if params[2]
271
+ # current_interface_or_router = router_class.new(*params[2..-1])
272
+ # else
273
+ # current_interface_or_router = router_class.new
274
+ # end
275
+ current_interface_or_router = setup_interface_or_router()
276
+ current_type = :ROUTER
277
+ current_interface_or_router.name = router_name
278
+ @routers[router_name] = current_interface_or_router
279
+
280
+ when 'ROUTE'
281
+ raise parser.error("No current router for #{keyword}") unless current_interface_or_router and current_type == :ROUTER
282
+
283
+ usage = "ROUTE <Interface Name>"
284
+ parser.verify_num_parameters(1, 1, usage)
285
+ interface_name = params[0].upcase
286
+ interface = @interfaces[interface_name]
287
+ raise parser.error("Unknown interface #{interface_name} mapped to router #{current_interface_or_router.name}") unless interface
288
+
289
+ unless current_interface_or_router.interfaces.include? interface
290
+ current_interface_or_router.interfaces << interface
291
+ interface.routers << current_interface_or_router
292
+ end
293
+
294
+ when 'BACKGROUND_TASK'
295
+ usage = "#{keyword} <Filename> <Specific Parameters>"
296
+ parser.verify_num_parameters(1, nil, usage)
297
+ # background_task = OpenC3.require_class(params[0])
298
+ if params[1]
299
+ @background_tasks << params
300
+ else
301
+ @background_tasks << params
302
+ end
303
+
304
+ when 'STOPPED'
305
+ parser.verify_num_parameters(0, 0, "#{keyword}")
306
+ raise parser.error("No BACKGROUND_TASK defined") if @background_tasks.empty?
307
+ # @background_tasks[-1].stopped = true
308
+
309
+ when 'COLLECT_METADATA'
310
+ parser.verify_num_parameters(0, 0, "#{keyword}")
311
+ @metadata = true
312
+
313
+ else
314
+ # blank lines will have a nil keyword and should not raise an exception
315
+ raise parser.error("Unknown keyword: #{keyword}") unless keyword.nil?
316
+ end # case
317
+ end # loop
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,294 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Modified by OpenC3, Inc.
17
+ # All changes Copyright 2022, OpenC3, Inc.
18
+ # All Rights Reserved
19
+
20
+ module OpenC3
21
+ # Encapsulates an {Interface} in a Ruby thread. When the thread is started by
22
+ # the {#start} method, it loops trying to connect. It then continously reads
23
+ # from the interface while handling the packets it receives.
24
+ class InterfaceThread
25
+ # The number of bytes to print when an UNKNOWN packet is received
26
+ UNKNOWN_BYTES_TO_PRINT = 36
27
+
28
+ # @return [#call()] Callback which is called if the #{Interface#connect}
29
+ # method succeeds
30
+ attr_accessor :connection_success_callback
31
+ # @return [#call(Exception)] Callback which is called if the
32
+ # {Interface#connect} method throws an exception.
33
+ attr_accessor :connection_failed_callback
34
+ # @return [#call(Exception|nil)] Callback which is called if the
35
+ # interface connection is lost.
36
+ attr_accessor :connection_lost_callback
37
+ # @return [#call(Packet)] Callback which is called when a packet has been
38
+ # received from the interface and identified.
39
+ attr_accessor :identified_packet_callback
40
+ # @return [#call(Exception)] Callback which is called if the
41
+ # InterfaceThread dies for any reason.
42
+ attr_accessor :fatal_exception_callback
43
+
44
+ # @param interface [Interface] The interface to create a thread for
45
+ def initialize(interface)
46
+ @interface = interface
47
+ @connection_success_callback = nil
48
+ @connection_failed_callback = nil
49
+ @connection_lost_callback = nil
50
+ @identified_packet_callback = nil
51
+ @fatal_exception_callback = nil
52
+ @thread = nil
53
+ @thread_sleeper = Sleeper.new
54
+ @connection_failed_messages = []
55
+ @connection_lost_messages = []
56
+ @mutex = Mutex.new
57
+ end
58
+
59
+ # Create and start the Ruby thread that will encapsulate the interface.
60
+ # Creates a while loop that waits for {Interface#connect} to succeed. Then
61
+ # calls {Interface#read} and handles all the incoming packets.
62
+ def start
63
+ @thread_sleeper = Sleeper.new
64
+ @thread = Thread.new do
65
+ @cancel_thread = false
66
+ begin
67
+ if @interface.read_allowed?
68
+ Logger.info "Starting packet reading for #{@interface.name}"
69
+ else
70
+ Logger.info "Starting connection maintenance for #{@interface.name}"
71
+ end
72
+ while true
73
+ break if @cancel_thread
74
+
75
+ unless @interface.connected?
76
+ begin
77
+ @mutex.synchronize do
78
+ # We need to make sure connect is not called after stop() has been called
79
+ connect() unless @cancel_thread
80
+ end
81
+ break if @cancel_thread
82
+ rescue Exception => connect_error
83
+ handle_connection_failed(connect_error)
84
+ if @cancel_thread
85
+ break
86
+ else
87
+ next
88
+ end
89
+ end
90
+ end
91
+
92
+ if @interface.read_allowed?
93
+ begin
94
+ packet = @interface.read
95
+ unless packet
96
+ Logger.info "Clean disconnect from #{@interface.name} (returned nil)"
97
+ handle_connection_lost(nil)
98
+ if @cancel_thread
99
+ break
100
+ else
101
+ next
102
+ end
103
+ end
104
+ packet.received_time = Time.now.sys unless packet.received_time
105
+ rescue Exception => err
106
+ handle_connection_lost(err)
107
+ if @cancel_thread
108
+ break
109
+ else
110
+ next
111
+ end
112
+ end
113
+
114
+ handle_packet(packet)
115
+ else
116
+ @thread_sleeper.sleep(1)
117
+ handle_connection_lost(nil) if !@interface.connected?
118
+ end
119
+ end # loop
120
+ rescue Exception => error
121
+ if @fatal_exception_callback
122
+ @fatal_exception_callback.call(error)
123
+ else
124
+ Logger.error "Packet reading thread unexpectedly died for #{@interface.name}"
125
+ OpenC3.handle_fatal_exception(error)
126
+ end
127
+ end
128
+ Logger.info "Stopped packet reading for #{@interface.name}"
129
+ end # Thread.new
130
+ end # def start
131
+
132
+ # Disconnect from the interface and stop the thread
133
+ def stop
134
+ @mutex.synchronize do
135
+ # Need to make sure that @cancel_thread is set and the interface disconnected within
136
+ # mutex to ensure that connect() is not called when we want to stop()
137
+ @cancel_thread = true
138
+ @thread_sleeper.cancel
139
+ @interface.disconnect
140
+ end
141
+ OpenC3.kill_thread(self, @thread) if @thread and @thread != Thread.current
142
+ end
143
+
144
+ def graceful_kill
145
+ # Just to avoid warning
146
+ end
147
+
148
+ protected
149
+
150
+ def handle_packet(packet)
151
+ if packet.stored
152
+ # Stored telemetry does not update the current value table
153
+ identified_packet = System.telemetry.identify_and_define_packet(packet, @interface.target_names)
154
+ else
155
+ # Identify and update packet
156
+ if packet.identified?
157
+ begin
158
+ # Preidentifed packet - place it into the current value table
159
+ identified_packet = System.telemetry.update!(packet.target_name,
160
+ packet.packet_name,
161
+ packet.buffer)
162
+ rescue RuntimeError
163
+ # Packet identified but we don't know about it
164
+ # Clear packet_name and target_name and try to identify
165
+ Logger.warn "Received unknown identified telemetry: #{packet.target_name} #{packet.packet_name}"
166
+ packet.target_name = nil
167
+ packet.packet_name = nil
168
+ identified_packet = System.telemetry.identify!(packet.buffer,
169
+ @interface.target_names)
170
+ end
171
+ else
172
+ # Packet needs to be identified
173
+ identified_packet = System.telemetry.identify!(packet.buffer,
174
+ @interface.target_names)
175
+ end
176
+ end
177
+
178
+ if identified_packet
179
+ identified_packet.received_time = packet.received_time
180
+ identified_packet.stored = packet.stored
181
+ identified_packet.extra = packet.extra
182
+ packet = identified_packet
183
+ else
184
+ unknown_packet = System.telemetry.update!('UNKNOWN', 'UNKNOWN', packet.buffer)
185
+ unknown_packet.received_time = packet.received_time
186
+ unknown_packet.stored = packet.stored
187
+ unknown_packet.extra = packet.extra
188
+ packet = unknown_packet
189
+ data_length = packet.length
190
+ string = "#{@interface.name} - Unknown #{data_length} byte packet starting: "
191
+ num_bytes_to_print = [UNKNOWN_BYTES_TO_PRINT, data_length].min
192
+ data_to_print = packet.buffer(false)[0..(num_bytes_to_print - 1)]
193
+ data_to_print.each_byte do |byte|
194
+ string << sprintf("%02X", byte)
195
+ end
196
+ Logger.error string
197
+ end
198
+
199
+ target = System.targets[packet.target_name]
200
+ target.tlm_cnt += 1 if target
201
+ packet.received_count += 1
202
+ @identified_packet_callback.call(packet) if @identified_packet_callback
203
+
204
+ # Write to routers
205
+ @interface.routers.each do |router|
206
+ router.write(packet) if router.write_allowed? and router.connected?
207
+ rescue => err
208
+ Logger.error "Problem writing to router #{router.name} - #{err.class}:#{err.message}"
209
+ end
210
+
211
+ # Write to packet log writers
212
+ if packet.stored and !@interface.stored_packet_log_writer_pairs.empty?
213
+ @interface.stored_packet_log_writer_pairs.each do |packet_log_writer_pair|
214
+ packet_log_writer_pair.tlm_log_writer.write(packet)
215
+ end
216
+ else
217
+ @interface.packet_log_writer_pairs.each do |packet_log_writer_pair|
218
+ # Write errors are handled by the log writer
219
+ packet_log_writer_pair.tlm_log_writer.write(packet)
220
+ end
221
+ end
222
+ end
223
+
224
+ def handle_connection_failed(connect_error)
225
+ if @connection_failed_callback
226
+ @connection_failed_callback.call(connect_error)
227
+ else
228
+ Logger.error "#{@interface.name} Connection Failed: #{connect_error.formatted(false, false)}"
229
+ case connect_error
230
+ when Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ENOTSOCK, Errno::EHOSTUNREACH, IOError
231
+ # Do not write an exception file for these extremely common cases
232
+ else
233
+ if RuntimeError === connect_error and (connect_error.message =~ /canceled/ or connect_error.message =~ /timeout/)
234
+ # Do not write an exception file for these extremely common cases
235
+ else
236
+ Logger.error connect_error.formatted
237
+ unless @connection_failed_messages.include?(connect_error.message)
238
+ OpenC3.write_exception_file(connect_error)
239
+ @connection_failed_messages << connect_error.message
240
+ end
241
+ end
242
+ end
243
+ end
244
+ disconnect()
245
+ end
246
+
247
+ def handle_connection_lost(err)
248
+ if @connection_lost_callback
249
+ @connection_lost_callback.call(err)
250
+ else
251
+ if err
252
+ Logger.info "Connection Lost for #{@interface.name}: #{err.formatted(false, false)}"
253
+ case err
254
+ when Errno::ECONNABORTED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EBADF, Errno::ENOTSOCK, IOError
255
+ # Do not write an exception file for these extremely common cases
256
+ else
257
+ Logger.error err.formatted
258
+ unless @connection_lost_messages.include?(err.message)
259
+ OpenC3.write_exception_file(err)
260
+ @connection_lost_messages << err.message
261
+ end
262
+ end
263
+ else
264
+ Logger.info "Connection Lost for #{@interface.name}"
265
+ end
266
+ end
267
+ disconnect()
268
+ end
269
+
270
+ def connect
271
+ Logger.info "Connecting to #{@interface.name}..."
272
+ @interface.connect
273
+ if @connection_success_callback
274
+ @connection_success_callback.call
275
+ else
276
+ Logger.info "#{@interface.name} Connection Success"
277
+ end
278
+ end
279
+
280
+ def disconnect
281
+ @interface.disconnect
282
+
283
+ # If the interface is set to auto_reconnect then delay so the thread
284
+ # can come back around and allow the interface a chance to reconnect.
285
+ if @interface.auto_reconnect
286
+ if !@cancel_thread
287
+ @thread_sleeper.sleep(@interface.reconnect_delay)
288
+ end
289
+ else
290
+ stop()
291
+ end
292
+ end
293
+ end # class InterfaceThread
294
+ end