cosmos 3.9.2 → 4.0.0

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 (438) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +23 -0
  3. data/.travis.yml +1 -0
  4. data/.yardopts +3 -0
  5. data/Gemfile +1 -1
  6. data/Manifest.txt +137 -52
  7. data/Rakefile +50 -44
  8. data/autohotkey/config/system/system.txt +0 -5
  9. data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +6 -1
  10. data/autohotkey/config/targets/INST/screens/extra.txt +19 -0
  11. data/autohotkey/config/targets/INST/sequences/run_sequence.txt +1 -0
  12. data/autohotkey/config/targets/META/screens/data.txt +12 -0
  13. data/autohotkey/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
  14. data/autohotkey/config/targets/{COSMOS/cmd_tlm/cosmos_server_cmds.txt → SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
  15. data/autohotkey/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
  16. data/autohotkey/config/targets/SYSTEM/screens/limits_change.txt +14 -0
  17. data/autohotkey/config/targets/SYSTEM/screens/meta.txt +14 -0
  18. data/autohotkey/config/targets/SYSTEM/target.txt +12 -0
  19. data/autohotkey/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
  20. data/autohotkey/config/tools/test_runner/test_runner2.txt +1 -1
  21. data/autohotkey/tools/CmdSequence +14 -0
  22. data/autohotkey/tools/CmdSequenceAHK +23 -0
  23. data/autohotkey/tools/CmdSequenceAHK2 +16 -0
  24. data/autohotkey/tools/cmd_extractor.ahk +2 -2
  25. data/autohotkey/tools/cmd_sender.ahk +4 -6
  26. data/autohotkey/tools/cmd_sequence.ahk +215 -0
  27. data/autohotkey/tools/cmd_sequence2.ahk +23 -0
  28. data/autohotkey/tools/data_viewer.ahk +2 -3
  29. data/autohotkey/tools/limits_monitor.ahk +9 -11
  30. data/autohotkey/tools/open_gl_builder.ahk +1 -2
  31. data/autohotkey/tools/packet_viewer.ahk +51 -35
  32. data/autohotkey/tools/replay.ahk +1 -2
  33. data/autohotkey/tools/script_runner.ahk +1 -2
  34. data/autohotkey/tools/script_runner2.ahk +1 -2
  35. data/autohotkey/tools/test_runner2.ahk +1 -5
  36. data/autohotkey/tools/test_runner3.ahk +1 -3
  37. data/autohotkey/tools/tlm_grapher.ahk +1 -3
  38. data/autohotkey/tools/tlm_grapher3.ahk +1 -2
  39. data/autohotkey/tools/tlm_viewer.ahk +8 -3
  40. data/autohotkey/tools/tlm_viewer2.ahk +2 -3
  41. data/autohotkey/tools/tlm_viewer5.ahk +1 -2
  42. data/cosmos.gemspec +26 -20
  43. data/data/cmd_sequence.png +0 -0
  44. data/data/config/_array_params.yaml +23 -0
  45. data/data/config/_id_items.yaml +24 -0
  46. data/data/config/_id_params.yaml +58 -0
  47. data/data/config/_interfaces.yaml +206 -0
  48. data/data/config/_items.yaml +20 -0
  49. data/data/config/_params.yaml +58 -0
  50. data/data/config/cmd_tlm_server.yaml +110 -0
  51. data/data/config/command.yaml +38 -0
  52. data/data/config/command_modifiers.yaml +127 -0
  53. data/data/config/command_telemetry.yaml +3 -0
  54. data/data/config/data_viewer.yaml +43 -0
  55. data/data/config/handbook_creator.yaml +23 -0
  56. data/data/config/housekeeping_params.yaml +71 -0
  57. data/data/config/interface_modifiers.yaml +44 -0
  58. data/data/config/item_modifiers.yaml +172 -0
  59. data/data/config/launcher.yaml +117 -0
  60. data/data/config/limits_monitor.yaml +53 -0
  61. data/data/config/linegraph_params.yaml +30 -0
  62. data/data/config/linegraph_plot.yaml +106 -0
  63. data/data/config/page_modifiers.yaml +128 -0
  64. data/data/config/param_item_modifiers.yaml +41 -0
  65. data/data/config/parameter_modifiers.yaml +144 -0
  66. data/data/config/protocols.yaml +257 -0
  67. data/data/config/screen.yaml +151 -0
  68. data/data/config/script_runner.yaml +15 -0
  69. data/data/config/system.yaml +153 -0
  70. data/data/config/table_manager.yaml +76 -0
  71. data/data/config/table_parameter_modifiers.yaml +9 -0
  72. data/data/config/target.yaml +71 -0
  73. data/data/config/telemetry.yaml +73 -0
  74. data/data/config/telemetry_modifiers.yaml +129 -0
  75. data/data/config/test_runner.yaml +118 -0
  76. data/data/config/tlm_extractor.yaml +109 -0
  77. data/data/config/tlm_grapher.yaml +78 -0
  78. data/data/config/tlm_viewer.yaml +107 -0
  79. data/data/config/unknown.yaml +3 -0
  80. data/data/config/widgets.yaml +1339 -0
  81. data/data/config/xy_params.yaml +50 -0
  82. data/data/config/xy_plot.yaml +12 -0
  83. data/data/config_editor.png +0 -0
  84. data/data/crc.txt +172 -161
  85. data/data/delete.png +0 -0
  86. data/demo/config/data/crc.txt +56 -36
  87. data/demo/config/data/meta_init.txt +1 -4
  88. data/demo/config/system/system.txt +15 -3
  89. data/demo/config/system/system2.txt +13 -3
  90. data/demo/config/targets/EXAMPLE/lib/example_interface.rb +2 -6
  91. data/demo/config/targets/EXAMPLE/target.txt +3 -1
  92. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -0
  93. data/demo/config/targets/INST/lib/inst_dump_component.rb +34 -0
  94. data/demo/config/targets/INST/screens/adcs.txt +39 -15
  95. data/demo/config/targets/INST/screens/commanding.txt +26 -19
  96. data/demo/config/targets/INST/screens/spacing_box.txt +44 -0
  97. data/demo/config/targets/INST/screens/spacing_grid.txt +78 -0
  98. data/demo/config/targets/INST/screens/tabs.txt +0 -2
  99. data/demo/config/targets/INST/sequences/sequence.tsv +3 -0
  100. data/demo/config/targets/INST/tables/EventAction.csv +9 -0
  101. data/demo/config/targets/INST/tables/EventAction.dat +0 -0
  102. data/demo/config/targets/INST/tables/McConfigTable.csv +20 -0
  103. data/demo/config/targets/INST/tables/McConfigTable.dat +0 -0
  104. data/demo/config/targets/INST/target.txt +4 -0
  105. data/demo/config/targets/INST/tools/data_viewer/data_viewer.txt +2 -0
  106. data/demo/config/targets/INST/tools/data_viewer/data_viewer2.txt +2 -0
  107. data/demo/config/targets/INST/tools/table_manager/EventAction_def.txt +6 -0
  108. data/demo/config/targets/INST/tools/table_manager/McConfigTable_def.txt +38 -0
  109. data/demo/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -3
  110. data/demo/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
  111. data/demo/config/targets/{COSMOS/cmd_tlm/cosmos_server_cmds.txt → SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
  112. data/demo/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
  113. data/demo/config/targets/{COSMOS → SYSTEM}/cmd_tlm_server.txt +2 -2
  114. data/demo/config/targets/SYSTEM/lib/limits_groups.rb +39 -0
  115. data/demo/config/targets/SYSTEM/screens/status.txt +1 -1
  116. data/demo/config/targets/SYSTEM/target.txt +12 -0
  117. data/demo/config/targets/TEMPLATED/cmd_tlm_server.txt +1 -1
  118. data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +8 -5
  119. data/demo/config/targets/TEMPLATED/target.txt +2 -0
  120. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +15 -6
  121. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +13 -5
  122. data/demo/config/tools/data_viewer/data_viewer.txt +9 -0
  123. data/demo/config/tools/launcher/launcher.txt +9 -6
  124. data/demo/config/tools/launcher/launcher2.txt +16 -13
  125. data/demo/config/tools/launcher/launcher_mini.txt +45 -0
  126. data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +12 -11
  127. data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +12 -11
  128. data/demo/config/tools/test_runner/test_runner.txt +1 -1
  129. data/demo/config/tools/tlm_viewer/tlm_viewer.txt +5 -5
  130. data/demo/lib/example_background_task.rb +9 -5
  131. data/demo/lib/example_target.rb +5 -15
  132. data/demo/lib/scpi_target.rb +4 -10
  133. data/demo/procedures/cosmos_api_test.rb +17 -0
  134. data/demo/tools/CmdSequence +16 -0
  135. data/demo/tools/CmdSequence.bat +9 -0
  136. data/demo/tools/ConfigEditor +16 -0
  137. data/demo/tools/ConfigEditor.bat +9 -0
  138. data/demo/tools/mac/CmdSequence.app/Contents/Info.plist +38 -0
  139. data/demo/tools/mac/CmdSequence.app/Contents/MacOS/CmdSequence.rb +16 -0
  140. data/demo/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +10 -0
  141. data/demo/tools/mac/CmdSequence.app/Contents/MacOS/tool_launch.rb +38 -0
  142. data/demo/tools/mac/CmdSequence.app/Contents/Resources/appIcon.icns +0 -0
  143. data/ext/cosmos/ext/packet/packet.c +5 -5
  144. data/install/config/data/crc.txt +12 -8
  145. data/install/config/system/system.txt +13 -3
  146. data/install/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +14 -0
  147. data/install/config/targets/SYSTEM/target.txt +12 -0
  148. data/install/tools/CmdSequence +16 -0
  149. data/install/tools/CmdSequence.bat +9 -0
  150. data/install/tools/ConfigEditor +16 -0
  151. data/install/tools/ConfigEditor.bat +9 -0
  152. data/install/tools/mac/CmdSequence.app/Contents/Info.plist +38 -0
  153. data/install/tools/mac/CmdSequence.app/Contents/MacOS/CmdSequence.rb +16 -0
  154. data/install/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +10 -0
  155. data/install/tools/mac/CmdSequence.app/Contents/MacOS/tool_launch.rb +38 -0
  156. data/install/tools/mac/CmdSequence.app/Contents/Resources/appIcon.icns +0 -0
  157. data/lib/cosmos.rb +1 -1
  158. data/lib/cosmos/config/config_parser.rb +147 -59
  159. data/lib/cosmos/config/meta_config_parser.rb +57 -0
  160. data/lib/cosmos/conversions/polynomial_conversion.rb +20 -4
  161. data/lib/cosmos/conversions/unix_time_conversion.rb +4 -4
  162. data/lib/cosmos/core_ext/array.rb +45 -5
  163. data/lib/cosmos/core_ext/cosmos_io.rb +31 -15
  164. data/lib/cosmos/core_ext/file.rb +2 -2
  165. data/lib/cosmos/core_ext/kernel.rb +1 -6
  166. data/lib/cosmos/core_ext/objectspace.rb +0 -2
  167. data/lib/cosmos/core_ext/string.rb +27 -4
  168. data/lib/cosmos/core_ext/time.rb +39 -10
  169. data/lib/cosmos/gui/choosers/combobox_chooser.rb +37 -26
  170. data/lib/cosmos/gui/choosers/file_chooser.rb +23 -6
  171. data/lib/cosmos/gui/choosers/float_chooser.rb +13 -11
  172. data/lib/cosmos/gui/choosers/integer_chooser.rb +13 -11
  173. data/lib/cosmos/gui/choosers/string_chooser.rb +18 -36
  174. data/lib/cosmos/gui/choosers/telemetry_chooser.rb +64 -64
  175. data/lib/cosmos/gui/choosers/value_chooser.rb +15 -15
  176. data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -13
  177. data/lib/cosmos/gui/dialogs/calendar_dialog.rb +11 -3
  178. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +1 -1
  179. data/lib/cosmos/gui/dialogs/details_dialog.rb +1 -1
  180. data/lib/cosmos/gui/dialogs/exception_dialog.rb +7 -7
  181. data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +20 -15
  182. data/lib/cosmos/gui/dialogs/interface_raw_dialog.rb +143 -0
  183. data/lib/cosmos/gui/dialogs/legal_dialog.rb +6 -5
  184. data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +5 -2
  185. data/lib/cosmos/gui/dialogs/progress_dialog.rb +1 -1
  186. data/lib/cosmos/gui/dialogs/pry_dialog.rb +4 -4
  187. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +3 -0
  188. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +7 -6
  189. data/lib/cosmos/gui/dialogs/splash.rb +1 -1
  190. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +1 -1
  191. data/lib/cosmos/gui/dialogs/tlm_graph_dialog.rb +114 -0
  192. data/lib/cosmos/gui/line_graph/line_graph.rb +9 -10
  193. data/lib/cosmos/gui/line_graph/line_graph_dialog.rb +7 -5
  194. data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +3 -7
  195. data/lib/cosmos/gui/line_graph/line_graph_popups.rb +3 -8
  196. data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +2 -7
  197. data/lib/cosmos/gui/line_graph/overview_graph.rb +6 -1
  198. data/lib/cosmos/gui/opengl/earth_model.rb +6 -3
  199. data/lib/cosmos/gui/opengl/gl_bounds.rb +11 -23
  200. data/lib/cosmos/gui/opengl/gl_light.rb +3 -4
  201. data/lib/cosmos/gui/opengl/gl_material.rb +3 -4
  202. data/lib/cosmos/gui/opengl/gl_scene.rb +10 -4
  203. data/lib/cosmos/gui/opengl/gl_shape.rb +6 -2
  204. data/lib/cosmos/gui/opengl/gl_viewer.rb +5 -5
  205. data/lib/cosmos/gui/opengl/gl_viewport.rb +11 -12
  206. data/lib/cosmos/gui/opengl/moon_model.rb +6 -3
  207. data/lib/cosmos/gui/opengl/stl_reader.rb +8 -9
  208. data/lib/cosmos/gui/opengl/stl_shape.rb +4 -5
  209. data/lib/cosmos/gui/opengl/texture_mapped_sphere.rb +7 -7
  210. data/lib/cosmos/gui/qt.rb +1 -1
  211. data/lib/cosmos/gui/qt_tool.rb +21 -10
  212. data/lib/cosmos/gui/text/completion.rb +23 -2
  213. data/lib/cosmos/gui/text/completion_text_edit.rb +38 -23
  214. data/lib/cosmos/gui/utilities/analyze_log.rb +1 -1
  215. data/lib/cosmos/gui/utilities/screenshot.rb +2 -2
  216. data/lib/cosmos/gui/widgets/full_text_search_line_edit.rb +11 -1
  217. data/lib/cosmos/gui/widgets/packet_log_frame.rb +19 -6
  218. data/lib/cosmos/interfaces.rb +10 -0
  219. data/lib/cosmos/interfaces/cmd_tlm_server_interface.rb +28 -47
  220. data/lib/cosmos/interfaces/interface.rb +240 -22
  221. data/lib/cosmos/interfaces/linc_interface.rb +3 -5
  222. data/lib/cosmos/interfaces/protocols/burst_protocol.rb +173 -0
  223. data/lib/cosmos/interfaces/protocols/crc_protocol.rb +141 -0
  224. data/lib/cosmos/{streams/fixed_stream_protocol.rb → interfaces/protocols/fixed_protocol.rb} +40 -37
  225. data/lib/cosmos/{streams/length_stream_protocol.rb → interfaces/protocols/length_protocol.rb} +55 -48
  226. data/lib/cosmos/interfaces/protocols/override_protocol.rb +52 -0
  227. data/lib/cosmos/interfaces/protocols/preidentified_protocol.rb +141 -0
  228. data/lib/cosmos/interfaces/protocols/protocol.rb +60 -0
  229. data/lib/cosmos/interfaces/protocols/template_protocol.rb +209 -0
  230. data/lib/cosmos/interfaces/protocols/terminated_protocol.rb +81 -0
  231. data/lib/cosmos/interfaces/serial_interface.rb +28 -23
  232. data/lib/cosmos/interfaces/simulated_target_interface.rb +27 -16
  233. data/lib/cosmos/interfaces/stream_interface.rb +36 -108
  234. data/lib/cosmos/interfaces/tcpip_client_interface.rb +21 -21
  235. data/lib/cosmos/interfaces/tcpip_server_interface.rb +555 -94
  236. data/lib/cosmos/interfaces/udp_interface.rb +51 -83
  237. data/lib/cosmos/io/buffered_file.rb +92 -2
  238. data/lib/cosmos/io/json_drb.rb +2 -2
  239. data/lib/cosmos/io/posix_serial_driver.rb +3 -1
  240. data/lib/cosmos/io/raw_logger.rb +3 -3
  241. data/lib/cosmos/io/serial_driver.rb +14 -5
  242. data/lib/cosmos/io/win32_serial_driver.rb +16 -4
  243. data/lib/cosmos/packet_logs.rb +0 -1
  244. data/lib/cosmos/packet_logs/packet_log_reader.rb +11 -1
  245. data/lib/cosmos/packet_logs/packet_log_writer.rb +31 -13
  246. data/lib/cosmos/packets/binary_accessor.rb +599 -32
  247. data/lib/cosmos/packets/commands.rb +48 -24
  248. data/lib/cosmos/packets/packet.rb +140 -54
  249. data/lib/cosmos/packets/packet_config.rb +0 -2
  250. data/lib/cosmos/packets/parsers/packet_item_parser.rb +10 -2
  251. data/lib/cosmos/packets/structure.rb +81 -33
  252. data/lib/cosmos/packets/structure_item.rb +45 -5
  253. data/lib/cosmos/packets/telemetry.rb +149 -55
  254. data/lib/cosmos/script/api_shared.rb +1000 -0
  255. data/lib/cosmos/script/commands.rb +2 -2
  256. data/lib/cosmos/script/extract.rb +19 -4
  257. data/lib/cosmos/script/limits.rb +2 -0
  258. data/lib/cosmos/script/script.rb +1 -1
  259. data/lib/cosmos/script/scripting.rb +4 -784
  260. data/lib/cosmos/script/telemetry.rb +44 -23
  261. data/lib/cosmos/script/tools.rb +15 -69
  262. data/lib/cosmos/streams/serial_stream.rb +12 -19
  263. data/lib/cosmos/streams/stream.rb +2 -11
  264. data/lib/cosmos/streams/tcpip_socket_stream.rb +3 -13
  265. data/lib/cosmos/system/system.rb +187 -31
  266. data/lib/cosmos/system/target.rb +11 -2
  267. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +12 -11
  268. data/lib/cosmos/tools/cmd_sender/{cmd_sender_item_delegate.rb → cmd_param_table_item_delegate.rb} +11 -10
  269. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +209 -164
  270. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +652 -0
  271. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +510 -0
  272. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +194 -0
  273. data/lib/cosmos/tools/cmd_tlm_server/api.rb +179 -5
  274. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +31 -14
  275. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +23 -16
  276. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +92 -20
  277. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +1 -1
  278. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +17 -4
  279. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +0 -5
  280. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +1 -2
  281. data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +4 -4
  282. data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +121 -0
  283. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +8 -4
  284. data/lib/cosmos/tools/config_editor/config_editor.rb +720 -0
  285. data/lib/cosmos/tools/config_editor/config_editor_frame.rb +675 -0
  286. data/lib/cosmos/tools/data_viewer/data_viewer.rb +44 -27
  287. data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +8 -22
  288. data/lib/cosmos/tools/launcher/launcher.rb +29 -12
  289. data/lib/cosmos/tools/launcher/launcher_config.rb +1 -1
  290. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +153 -42
  291. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +44 -6
  292. data/lib/cosmos/tools/replay/replay.rb +36 -20
  293. data/lib/cosmos/tools/replay/replay_server.rb +1 -1
  294. data/lib/cosmos/tools/script_runner/script_runner_config.rb +1 -1
  295. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +31 -21
  296. data/lib/cosmos/tools/table_manager/table_config.rb +9 -3
  297. data/lib/cosmos/tools/table_manager/table_manager.rb +27 -7
  298. data/lib/cosmos/tools/test_runner/results_writer.rb +6 -6
  299. data/lib/cosmos/tools/test_runner/test_runner.rb +4 -6
  300. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +4 -5
  301. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -1
  302. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +1 -1
  303. data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +23 -6
  304. data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +44 -3
  305. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +20 -7
  306. data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +1 -1
  307. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +11 -4
  308. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_plot_editor.rb +2 -2
  309. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +1 -1
  310. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +16 -0
  311. data/lib/cosmos/tools/tlm_viewer/screen.rb +36 -32
  312. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +59 -50
  313. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +2 -2
  314. data/lib/cosmos/tools/tlm_viewer/widgets.rb +1 -0
  315. data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +1 -0
  316. data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +22 -4
  317. data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +9 -0
  318. data/lib/cosmos/tools/tlm_viewer/widgets/spacer_widget.rb +55 -0
  319. data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +3 -2
  320. data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +3 -2
  321. data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +12 -12
  322. data/lib/cosmos/top_level.rb +34 -24
  323. data/lib/cosmos/utilities/crc.rb +108 -6
  324. data/lib/cosmos/utilities/csv.rb +68 -14
  325. data/lib/cosmos/utilities/logger.rb +2 -2
  326. data/lib/cosmos/utilities/low_fragmentation_array.rb +9 -1
  327. data/lib/cosmos/version.rb +6 -6
  328. data/lib/cosmos/win32/win32_main.rb +50 -46
  329. data/run_gui_tests.bat +3 -1
  330. data/spec/conversions/unix_time_formatted_conversion_spec.rb +2 -2
  331. data/spec/conversions/unix_time_seconds_conversion_spec.rb +2 -2
  332. data/spec/core_ext/file_spec.rb +1 -1
  333. data/spec/core_ext/objectspace_spec.rb +12 -9
  334. data/spec/core_ext/string_spec.rb +6 -0
  335. data/spec/core_ext/time_spec.rb +10 -0
  336. data/spec/gui/line_graph/line_clip_spec.rb +226 -224
  337. data/spec/gui/qt_spec.rb +81 -79
  338. data/spec/install/config/system/system.txt +0 -6
  339. data/spec/install/config/targets/INST/cmd_tlm/inst_cmd_linc.txt +5 -5
  340. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm_linc.txt +8 -8
  341. data/spec/install/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
  342. data/{install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt → spec/install/config/targets/SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
  343. data/spec/install/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
  344. data/spec/install/config/targets/{COSMOS → SYSTEM}/cmd_tlm_server.txt +2 -2
  345. data/spec/install/config/targets/SYSTEM/screens/status.txt +12 -0
  346. data/spec/install/config/targets/SYSTEM/target.txt +12 -0
  347. data/spec/interfaces/cmd_tlm_server_interface_spec.rb +9 -13
  348. data/spec/interfaces/interface_spec.rb +402 -18
  349. data/spec/interfaces/linc_interface_spec.rb +37 -39
  350. data/spec/interfaces/protocols/burst_protocol_spec.rb +300 -0
  351. data/spec/interfaces/protocols/crc_protocol_spec.rb +709 -0
  352. data/spec/interfaces/protocols/fixed_protocol_spec.rb +119 -0
  353. data/spec/interfaces/protocols/length_protocol_spec.rb +499 -0
  354. data/spec/interfaces/protocols/override_protocol_spec.rb +158 -0
  355. data/spec/interfaces/protocols/preidentified_protocol_spec.rb +149 -0
  356. data/spec/interfaces/protocols/template_protocol_spec.rb +218 -0
  357. data/spec/interfaces/protocols/terminated_protocol_spec.rb +174 -0
  358. data/spec/interfaces/serial_interface_spec.rb +35 -34
  359. data/spec/interfaces/simulated_target_interface_spec.rb +13 -13
  360. data/spec/interfaces/tcpip_client_interface_spec.rb +21 -16
  361. data/spec/interfaces/tcpip_server_interface_spec.rb +66 -69
  362. data/spec/interfaces/udp_interface_spec.rb +120 -55
  363. data/spec/io/serial_driver_spec.rb +41 -39
  364. data/spec/io/udp_sockets_spec.rb +13 -8
  365. data/spec/io/win32_serial_driver_spec.rb +62 -59
  366. data/spec/packet_logs/packet_log_reader_spec.rb +68 -47
  367. data/spec/packet_logs/packet_log_writer_spec.rb +7 -5
  368. data/spec/packets/commands_spec.rb +5 -5
  369. data/spec/packets/packet_spec.rb +2 -14
  370. data/spec/script/extract_spec.rb +21 -7
  371. data/spec/script/scripting_spec.rb +261 -6
  372. data/spec/script/telemetry_spec.rb +17 -9
  373. data/spec/spec_helper.rb +26 -10
  374. data/spec/streams/serial_stream_spec.rb +87 -82
  375. data/spec/streams/tcpip_client_stream_spec.rb +12 -4
  376. data/spec/streams/tcpip_socket_stream_spec.rb +5 -0
  377. data/spec/system/system_spec.rb +66 -50
  378. data/spec/system/target_spec.rb +33 -11
  379. data/spec/tools/cmd_tlm_server/api_spec.rb +5 -5
  380. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +75 -15
  381. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +125 -5
  382. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +244 -232
  383. data/spec/tools/cmd_tlm_server/commanding_spec.rb +18 -18
  384. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +124 -29
  385. data/spec/tools/cmd_tlm_server/interfaces_spec.rb +2 -2
  386. data/spec/tools/cmd_tlm_server/limits_groups_background_task_spec.rb +145 -0
  387. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +50 -10
  388. data/spec/tools/table_manager/tablemanager_core_spec.rb +0 -1
  389. data/spec/top_level/top_level_spec.rb +39 -11
  390. data/spec/utilities/csv_spec.rb +62 -20
  391. data/tasks/gemfile_stats.rake +6 -3
  392. data/test/performance/config/system/system_packets.txt +0 -1
  393. data/test/performance/config/system/system_threads.txt +0 -1
  394. metadata +177 -92
  395. data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
  396. data/autohotkey/config/targets/COSMOS/cmd_tlm_server.txt +0 -6
  397. data/autohotkey/config/targets/COSMOS/target.txt +0 -5
  398. data/autohotkey/userpath.txt +0 -1
  399. data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
  400. data/demo/config/targets/COSMOS/screens/limits_change.txt +0 -20
  401. data/demo/config/targets/COSMOS/screens/version.txt +0 -19
  402. data/demo/config/targets/COSMOS/target.txt +0 -11
  403. data/demo/config/targets/META/cmd_tlm/meta_cmd.txt +0 -10
  404. data/demo/config/targets/META/cmd_tlm/meta_tlm.txt +0 -13
  405. data/demo/userpath.txt +0 -1
  406. data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
  407. data/install/config/targets/COSMOS/cmd_tlm_server.txt +0 -6
  408. data/install/config/targets/COSMOS/screens/limits_change.txt +0 -20
  409. data/install/config/targets/COSMOS/screens/version.txt +0 -19
  410. data/install/config/targets/COSMOS/target.txt +0 -9
  411. data/install/config/targets/SYSTEM/README.txt +0 -1
  412. data/install/userpath.txt +0 -1
  413. data/lib/cosmos/io/tcpip_server.rb +0 -571
  414. data/lib/cosmos/packet_logs/meta_packet_log_writer.rb +0 -107
  415. data/lib/cosmos/streams/burst_stream_protocol.rb +0 -25
  416. data/lib/cosmos/streams/preidentified_stream_protocol.rb +0 -118
  417. data/lib/cosmos/streams/stream_protocol.rb +0 -373
  418. data/lib/cosmos/streams/template_stream_protocol.rb +0 -140
  419. data/lib/cosmos/streams/terminated_stream_protocol.rb +0 -85
  420. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +0 -41
  421. data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
  422. data/spec/install/config/targets/COSMOS/screens/limits_change.txt +0 -20
  423. data/spec/install/config/targets/COSMOS/screens/version.txt +0 -19
  424. data/spec/install/config/targets/COSMOS/target.txt +0 -5
  425. data/spec/install/config/targets/META/cmd_tlm/meta_cmd.txt +0 -4
  426. data/spec/install/config/targets/META/cmd_tlm/meta_tlm.txt +0 -4
  427. data/spec/install/userpath.txt +0 -1
  428. data/spec/interfaces/stream_interface_spec.rb +0 -157
  429. data/spec/io/tcpip_server_spec.rb +0 -338
  430. data/spec/packet_logs/meta_packet_log_writer_spec.rb +0 -170
  431. data/spec/streams/burst_stream_protocol_spec.rb +0 -32
  432. data/spec/streams/fixed_stream_protocol_spec.rb +0 -113
  433. data/spec/streams/length_stream_protocol_spec.rb +0 -300
  434. data/spec/streams/preidentified_stream_protocol_spec.rb +0 -121
  435. data/spec/streams/stream_protocol_spec.rb +0 -346
  436. data/spec/streams/template_stream_protocol_spec.rb +0 -156
  437. data/spec/streams/terminated_stream_protocol_spec.rb +0 -127
  438. data/test/performance/userpath.txt +0 -1
@@ -1,15 +0,0 @@
1
- TELEMETRY COSMOS VERSION BIG_ENDIAN "COSMOS version information"
2
- APPEND_ID_ITEM PKT_ID 8 UINT 1 "Packet ID"
3
- APPEND_ITEM COSMOS 240 STRING "COSMOS version"
4
- APPEND_ITEM RUBY 240 STRING "Ruby version"
5
- APPEND_ITEM CTDB 240 STRING "Command Telemetry Database Version"
6
- APPEND_ITEM USER 240 STRING "User Version"
7
-
8
- TELEMETRY COSMOS LIMITS_CHANGE BIG_ENDIAN "COSMOS limits change"
9
- APPEND_ID_ITEM PKT_ID 8 UINT 2 "Packet ID"
10
- APPEND_ITEM TARGET 240 STRING "Target name"
11
- APPEND_ITEM PACKET 240 STRING "Packet name"
12
- APPEND_ITEM ITEM 240 STRING "Item that changed limits state"
13
- APPEND_ITEM OLD_STATE 240 STRING "The old limit state"
14
- APPEND_ITEM NEW_STATE 240 STRING "The new limit state"
15
-
@@ -1,6 +0,0 @@
1
- # This is a segment of the main cmd_tlm_server.txt that will be used with
2
- # AUTO_INTERFACE_TARGETS or INTERFACE_TARGET
3
-
4
- INTERFACE COSMOSINT cmd_tlm_server_interface.rb
5
- TARGET COSMOS
6
- DISABLE_DISCONNECT
@@ -1,5 +0,0 @@
1
- # Ignored Parameters
2
- # IGNORE_PARAMETER parameter_name
3
- IGNORE_PARAMETER SYNC
4
- IGNORE_PARAMETER OPCODE
5
- IGNORE_PARAMETER LENGTH
@@ -1 +0,0 @@
1
- DO NOT DELETE THIS FILE! It is used by cosmos.rb to build the ::Cosmos::USERPATH directory.
@@ -1,15 +0,0 @@
1
- TELEMETRY COSMOS VERSION BIG_ENDIAN "COSMOS version information"
2
- APPEND_ID_ITEM PKT_ID 8 UINT 1 "Packet ID"
3
- APPEND_ITEM COSMOS 240 STRING "COSMOS version"
4
- APPEND_ITEM RUBY 240 STRING "Ruby version"
5
- APPEND_ITEM CTDB 240 STRING "Command Telemetry Database Version"
6
- APPEND_ITEM USER 240 STRING "User Version"
7
-
8
- TELEMETRY COSMOS LIMITS_CHANGE BIG_ENDIAN "COSMOS limits change"
9
- APPEND_ID_ITEM PKT_ID 8 UINT 2 "Packet ID"
10
- APPEND_ITEM TARGET 240 STRING "Target name"
11
- APPEND_ITEM PACKET 240 STRING "Packet name"
12
- APPEND_ITEM ITEM 240 STRING "Item that changed limits state"
13
- APPEND_ITEM OLD_STATE 240 STRING "The old limit state"
14
- APPEND_ITEM NEW_STATE 240 STRING "The new limit state"
15
-
@@ -1,20 +0,0 @@
1
- SCREEN AUTO AUTO 0.5
2
-
3
- VERTICAL
4
-
5
- TITLE "COSMOS Limits Change"
6
- SETTING BACKCOLOR 162 181 205
7
- SETTING TEXTCOLOR black
8
-
9
- LABELVALUE COSMOS LIMITS_CHANGE RECEIVED_TIMESECONDS WITH_UNITS 30
10
- LABELVALUE COSMOS LIMITS_CHANGE RECEIVED_TIMEFORMATTED WITH_UNITS 30
11
- LABELVALUE COSMOS LIMITS_CHANGE RECEIVED_COUNT WITH_UNITS 30
12
- LABELVALUE COSMOS LIMITS_CHANGE pkt_id WITH_UNITS 30
13
- LABELVALUE COSMOS LIMITS_CHANGE target WITH_UNITS 30
14
- LABELVALUE COSMOS limits_change PACKET WITH_UNITS 30
15
- LABELVALUE COSMOS limits_change ITEM WITH_UNITS 30
16
- LABELVALUE cosmos LIMITS_CHANGE OLD_STATE WITH_UNITS 30
17
- LABELVALUE cosmos LIMITS_CHANGE NEW_STATE WITH_UNITS 30
18
- END
19
-
20
-
@@ -1,19 +0,0 @@
1
- SCREEN AUTO AUTO 0.5
2
-
3
- VERTICAL
4
-
5
- TITLE "COSMOS Version"
6
- SETTING BACKCOLOR 162 181 205
7
- SETTING TEXTCOLOR black
8
-
9
- LABELVALUE COSMOS VERSION RECEIVED_TIMESECONDS WITH_UNITS 30
10
- LABELVALUE COSMOS VERSION RECEIVED_TIMEFORMATTED WITH_UNITS 30
11
- LABELVALUE COSMOS VERSION RECEIVED_COUNT WITH_UNITS 30
12
- LABELVALUE COSMOS VERSION PKT_ID WITH_UNITS 30
13
- LABELVALUE COSMOS VERSION COSMOS WITH_UNITS 30
14
- LABELVALUE COSMOS VERSION RUBY WITH_UNITS 30
15
- LABELVALUE COSMOS VERSION CTDB WITH_UNITS 30
16
- LABELVALUE COSMOS VERSION USER WITH_UNITS 30
17
- END
18
-
19
-
@@ -1,11 +0,0 @@
1
- # Ignored Parameters
2
- # IGNORE_PARAMETER parameter_name
3
- IGNORE_PARAMETER SYNC
4
- IGNORE_PARAMETER OPCODE
5
- IGNORE_PARAMETER LENGTH
6
-
7
- IGNORE_ITEM RECEIVED_COUNT
8
- IGNORE_ITEM RECEIVED_TIMESECONDS
9
- IGNORE_ITEM RECEIVED_TIMEFORMATTED
10
-
11
- AUTO_SCREEN_SUBSTITUTE
@@ -1,10 +0,0 @@
1
- COMMAND META DATA BIG_ENDIAN "Metadata"
2
- DISABLED
3
- APPEND_PARAMETER TEST_COUNT 32 INT 0 255 0 "Test Count"
4
- APPEND_PARAMETER TEST_ANGLE 64 FLOAT 0.0 100.0 0.0 "Test Angle"
5
- APPEND_PARAMETER TEST_TYPE 32 UINT 0 2 0 "Test Type"
6
- STATE TVAC 0
7
- STATE EMI 1
8
- STATE OTHER 2
9
- APPEND_PARAMETER VERSION 1024 STRING '' "Version Metadata"
10
- WRITE_CONVERSION new_packet_log_conversion.rb
@@ -1,13 +0,0 @@
1
- TELEMETRY META DATA BIG_ENDIAN "Metadata"
2
- APPEND_ITEM TEST_COUNT 32 INT "Test Count"
3
- GENERIC_WRITE_CONVERSION_START
4
- raise "Value must be 123" if value.to_i != 123
5
- value
6
- GENERIC_WRITE_CONVERSION_END
7
- APPEND_ITEM TEST_ANGLE 64 FLOAT "Test Angle"
8
- APPEND_ITEM TEST_TYPE 32 UINT "Test Type"
9
- STATE TVAC 0
10
- STATE EMI 1
11
- STATE OTHER 2
12
- APPEND_ITEM VERSION 1024 STRING "Version Metadata"
13
- WRITE_CONVERSION new_packet_log_conversion.rb
@@ -1 +0,0 @@
1
- DO NOT DELETE THIS FILE! It is used by cosmos.rb to build the ::Cosmos::USERPATH directory.
@@ -1,15 +0,0 @@
1
- TELEMETRY COSMOS VERSION BIG_ENDIAN "COSMOS version information"
2
- APPEND_ID_ITEM PKT_ID 8 UINT 1 "Packet ID"
3
- APPEND_ITEM COSMOS 240 STRING "COSMOS version"
4
- APPEND_ITEM RUBY 240 STRING "Ruby version"
5
- APPEND_ITEM CTDB 240 STRING "Command Telemetry Database Version"
6
- APPEND_ITEM USER 240 STRING "User Version"
7
-
8
- TELEMETRY COSMOS LIMITS_CHANGE BIG_ENDIAN "COSMOS limits change"
9
- APPEND_ID_ITEM PKT_ID 8 UINT 2 "Packet ID"
10
- APPEND_ITEM TARGET 240 STRING "Target name"
11
- APPEND_ITEM PACKET 240 STRING "Packet name"
12
- APPEND_ITEM ITEM 240 STRING "Item that changed limits state"
13
- APPEND_ITEM OLD_STATE 240 STRING "The old limit state"
14
- APPEND_ITEM NEW_STATE 240 STRING "The new limit state"
15
-
@@ -1,6 +0,0 @@
1
- # This is a segment of the main cmd_tlm_server.txt that will be used with
2
- # AUTO_INTERFACE_TARGETS or INTERFACE_TARGET
3
-
4
- INTERFACE COSMOSINT cmd_tlm_server_interface.rb
5
- TARGET COSMOS
6
- DISABLE_DISCONNECT
@@ -1,20 +0,0 @@
1
- SCREEN AUTO AUTO 0.5
2
-
3
- VERTICAL
4
-
5
- TITLE "COSMOS Limits Change"
6
- SETTING BACKCOLOR 162 181 205
7
- SETTING TEXTCOLOR black
8
-
9
- LABELVALUE COSMOS LIMITS_CHANGE RECEIVED_TIMESECONDS WITH_UNITS 30
10
- LABELVALUE COSMOS LIMITS_CHANGE RECEIVED_TIMEFORMATTED WITH_UNITS 30
11
- LABELVALUE COSMOS LIMITS_CHANGE RECEIVED_COUNT WITH_UNITS 30
12
- LABELVALUE COSMOS LIMITS_CHANGE pkt_id WITH_UNITS 30
13
- LABELVALUE COSMOS LIMITS_CHANGE target WITH_UNITS 30
14
- LABELVALUE COSMOS limits_change PACKET WITH_UNITS 30
15
- LABELVALUE COSMOS limits_change ITEM WITH_UNITS 30
16
- LABELVALUE cosmos LIMITS_CHANGE OLD_STATE WITH_UNITS 30
17
- LABELVALUE cosmos LIMITS_CHANGE NEW_STATE WITH_UNITS 30
18
- END
19
-
20
-
@@ -1,19 +0,0 @@
1
- SCREEN AUTO AUTO 0.5
2
-
3
- VERTICAL
4
-
5
- TITLE "COSMOS Version"
6
- SETTING BACKCOLOR 162 181 205
7
- SETTING TEXTCOLOR black
8
-
9
- LABELVALUE COSMOS VERSION RECEIVED_TIMESECONDS WITH_UNITS 30
10
- LABELVALUE COSMOS VERSION RECEIVED_TIMEFORMATTED WITH_UNITS 30
11
- LABELVALUE COSMOS VERSION RECEIVED_COUNT WITH_UNITS 30
12
- LABELVALUE COSMOS VERSION PKT_ID WITH_UNITS 30
13
- LABELVALUE COSMOS VERSION COSMOS WITH_UNITS 30
14
- LABELVALUE COSMOS VERSION RUBY WITH_UNITS 30
15
- LABELVALUE COSMOS VERSION CTDB WITH_UNITS 30
16
- LABELVALUE COSMOS VERSION USER WITH_UNITS 30
17
- END
18
-
19
-
@@ -1,9 +0,0 @@
1
- # Ignored Parameters
2
- # IGNORE_PARAMETER parameter_name
3
- IGNORE_PARAMETER SYNC
4
- IGNORE_PARAMETER OPCODE
5
- IGNORE_PARAMETER LENGTH
6
-
7
- IGNORE_ITEM RECEIVED_COUNT
8
- IGNORE_ITEM RECEIVED_TIMESECONDS
9
- IGNORE_ITEM RECEIVED_TIMEFORMATTED
@@ -1 +0,0 @@
1
- This file is here to make sure this folder is included in the release.
@@ -1 +0,0 @@
1
- DO NOT DELETE THIS FILE! It is used by cosmos.rb to build the ::Cosmos::USERPATH directory.
@@ -1,571 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2014 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 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
- require 'socket'
12
- require 'thread' # For Mutex
13
- require 'timeout' # For Timeout::Error
14
- require 'cosmos/streams/tcpip_socket_stream'
15
- require 'cosmos/config/config_parser'
16
-
17
- module Cosmos
18
-
19
- # TCP/IP Server which can both read and write on a single port or two
20
- # independent ports. A listen thread is setup which waits for client
21
- # connections. For each connection to the read port, a thread is spawned that
22
- # calls the read method from the stream protocol. This data is then
23
- # available by calling the TcpipServer read method. For each connection to the
24
- # write port, a thread is spawned that calls the write method from the stream
25
- # protocol when data is send to the TcpipServer via the write method.
26
- class TcpipServer
27
-
28
- # Callback method to call when a new client connects to the write port.
29
- # This method will be called with the StreamProtocol as the only argument.
30
- attr_accessor :write_connection_callback
31
- # Callback method to call when a new client connects to the read port.
32
- # This method will be called with the StreamProtocol as the only argument.
33
- attr_accessor :read_connection_callback
34
- # The number of bytes read from all connected sockets
35
- attr_accessor :bytes_read
36
- # The number of bytes written to the TcpipServer. This number does not vary
37
- # with the number of clients connected to the write port.
38
- attr_accessor :bytes_written
39
- # @return [RawLoggerPair] RawLoggerPair instance or nil
40
- attr_accessor :raw_logger_pair
41
- # @return [String] The ip address to bind to. Default to ANY (0.0.0.0)
42
- attr_accessor :listen_address
43
-
44
- # @param write_port [Integer] The server write port. Clients should connect
45
- # and expect to receive data from this port.
46
- # @param read_port [Integer] The server read port. Clients should connect
47
- # and expect to send data to this port.
48
- # @param write_timeout [Float|nil] The number of seconds to wait for the
49
- # write to complete. Pass nil to block until the write is complete.
50
- # @param read_timeout [Float|nil] The number of seconds to wait for the
51
- # read to complete. Pass nil to block until the read is complete.
52
- # @param stream_protocol_type [String] The name of the stream protocol to
53
- # use for both the read and write ports. This name is combined with
54
- # 'StreamProtocol' to result in a COSMOS StreamProtocol class.
55
- # @param stream_protocol_args [Array] The arguments to pass to the
56
- # StreamProtocol class constructor
57
- def initialize(write_port,
58
- read_port,
59
- write_timeout,
60
- read_timeout,
61
- stream_protocol_type,
62
- *stream_protocol_args)
63
- @write_port = ConfigParser.handle_nil(write_port)
64
- @write_port = Integer(write_port) if @write_port
65
- @read_port = ConfigParser.handle_nil(read_port)
66
- @read_port = Integer(read_port) if @read_port
67
- @write_timeout = ConfigParser.handle_nil(write_timeout)
68
- @write_timeout = @write_timeout.to_f if @write_timeout
69
- @read_timeout = ConfigParser.handle_nil(read_timeout)
70
- @read_timeout = @read_timeout.to_f if @read_timeout
71
-
72
- stream_protocol_class = stream_protocol_type.to_s.capitalize << 'StreamProtocol'
73
- @stream_protocol_class = Cosmos.require_class(stream_protocol_class.class_name_to_filename)
74
- @stream_protocol_args = stream_protocol_args
75
-
76
- @listen_sockets = []
77
- @listen_pipes = []
78
- @listen_threads = []
79
- @read_threads = []
80
- @write_stream_protocols = []
81
- @read_stream_protocols = []
82
- @write_queue = nil
83
- @write_queue = Queue.new if @write_port
84
- @read_queue = nil
85
- @read_queue = Queue.new if @read_port
86
- @write_mutex = nil
87
- @write_mutex = Mutex.new if @write_port
88
- @write_condition_variable = nil
89
- @write_condition_variable = ConditionVariable.new if @write_port
90
- @write_connection_callback = nil
91
- @read_connection_callback = nil
92
- @bytes_read = 0
93
- @bytes_written = 0
94
- @raw_logger_pair = nil
95
- @raw_logging_enabled = false
96
- @interface = nil
97
- @connection_mutex = Mutex.new
98
- @listen_address = Socket::INADDR_ANY
99
-
100
- @connected = false
101
- end
102
-
103
- # @param interface [Interface] Sets the higher level interface which is
104
- # using this TcpipServer. If the interface defines post_read_data,
105
- # post_read_packet, or pre_write_packet, then these methods will be
106
- # called over any subclass implementations within the stream protocol.
107
- def interface=(interface)
108
- @interface = interface
109
- end
110
-
111
- # Create the read and write port listen threads. Incoming connections will
112
- # spawn separate threads to process the reads and writes.
113
- def connect
114
- @cancel_threads = false
115
- if @read_queue
116
- # Empty the read queue of any residual
117
- begin
118
- @read_queue.pop(true) while @read_queue.length > 0
119
- rescue
120
- end
121
- end
122
- if @write_port == @read_port
123
- # Handle one socket case
124
- start_listen_thread(@read_port, true, true)
125
- else
126
- if @write_port
127
- start_listen_thread(@write_port, true, false)
128
- end
129
-
130
- if @read_port
131
- start_listen_thread(@read_port, false, true)
132
- end
133
- end
134
-
135
- if @write_port
136
- # Start write thread
137
- @write_thread = Thread.new do
138
- begin
139
- while true
140
- write_thread_body()
141
- break if @cancel_threads
142
- end
143
- rescue Exception => err
144
- @connection_mutex.synchronize do
145
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
146
- stream_protocol.disconnect
147
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
148
- end
149
- @write_stream_protocols.clear
150
- end
151
- Logger.instance.error("Tcpip server write thread unexpectedly died")
152
- Logger.instance.error(err.formatted)
153
- end
154
- end
155
- else
156
- @write_thread = nil
157
- end
158
- @connected = true
159
- end
160
-
161
- # @return [Boolean] Whether the server is listening for connections
162
- def connected?
163
- @connected
164
- end
165
-
166
- # Shutdowns the listener threads for both the read and write ports as well
167
- # as any client connections. As a part of shutting down client connections,
168
- # the {StreamProtocol#disconnect} method is called.
169
- def disconnect
170
- @cancel_threads = true
171
- @read_queue << nil if @read_queue
172
- @listen_pipes.each do |pipe|
173
- begin
174
- pipe.write('.')
175
- rescue Exception
176
- # Oh well
177
- end
178
- end
179
- @listen_pipes.clear
180
-
181
- # Shutdown Listen Thread(s)
182
- @listen_threads.each do |listen_thread|
183
- Cosmos.kill_thread(self, listen_thread)
184
- end
185
- @listen_threads.clear
186
-
187
- # Shutdown Listen Socket(s)
188
- @listen_sockets.each do |listen_socket|
189
- begin
190
- Cosmos.close_socket(listen_socket)
191
- rescue IOError
192
- # Ok may have been closed by the thread
193
- end
194
- end
195
- @listen_sockets.clear
196
-
197
- # Shutdown Read Stream Protocols - This should unblock read threads
198
- @connection_mutex.synchronize do
199
- @read_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
200
- stream_protocol.disconnect
201
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
202
- end
203
- @read_stream_protocols.clear
204
- end
205
-
206
- # Shutdown Read Threads
207
- @read_threads.each do |thread|
208
- Cosmos.kill_thread(self, thread)
209
- end
210
- @read_threads.clear
211
-
212
- # Shutdown Write Thread
213
- if @write_thread
214
- Cosmos.kill_thread(self, @write_thread)
215
- @write_thread = nil
216
- end
217
-
218
- # Shutdown Write Stream Protocols
219
- @connection_mutex.synchronize do
220
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
221
- stream_protocol.disconnect
222
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
223
- end
224
- @write_stream_protocols.clear
225
- end
226
-
227
- @connected = false
228
- end
229
-
230
- # Gracefully kill all the threads
231
- def graceful_kill
232
- # This method is just here to prevent warnings
233
- end
234
-
235
- # @return [Packet] Latest packet read from any of the connected clients.
236
- # Note this method blocks until data is available.
237
- def read
238
- return nil unless @read_queue
239
- packet = @read_queue.pop
240
- return nil unless packet
241
- @bytes_read += packet.buffer.length
242
- packet
243
- end
244
-
245
- # @param packet [Packet] Packet to write to all clients connected to the
246
- # write port.
247
- def write(packet)
248
- return unless @write_queue
249
- @write_queue << packet.clone
250
- @bytes_written += packet.buffer.length
251
- @write_condition_variable.broadcast
252
- end
253
-
254
- # @param data [String] Data to write to all clients connected to the
255
- # write port.
256
- def write_raw(data)
257
- return unless @write_queue
258
- packet = Packet.new(nil, nil)
259
- packet.buffer = data
260
- @write_queue << packet
261
- @bytes_written += data.length
262
- @write_condition_variable.broadcast
263
- end
264
-
265
- # @return [Integer] The number of packets waiting on the read queue
266
- def read_queue_size
267
- if @read_queue
268
- @read_queue.size
269
- else
270
- 0
271
- end
272
- end
273
-
274
- # @return [Integer] The number of packets waiting on the write queue
275
- def write_queue_size
276
- if @write_queue
277
- @write_queue.size
278
- else
279
- 0
280
- end
281
- end
282
-
283
- # @return [Integer] The number of connected clients
284
- def num_clients
285
- clients = []
286
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
287
- clients << [host_ip, port]
288
- end
289
- @read_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
290
- clients << [host_ip, port]
291
- end
292
- clients.uniq.length
293
- end
294
-
295
- # Start raw logging for this interface
296
- def start_raw_logging
297
- @raw_logging_enabled = true
298
- if @raw_logger_pair
299
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
300
- stream_protocol.stream.raw_logger_pair.start if stream_protocol.stream.raw_logger_pair
301
- end
302
- @read_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
303
- stream_protocol.stream.raw_logger_pair.start if stream_protocol.stream.raw_logger_pair
304
- end
305
- end
306
- end
307
-
308
- # Stop raw logging for this interface
309
- def stop_raw_logging
310
- @raw_logging_enabled = false
311
- if @raw_logger_pair
312
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
313
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
314
- end
315
- @read_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
316
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
317
- end
318
- end
319
- end
320
-
321
- protected
322
-
323
- def start_listen_thread(port, listen_write = false, listen_read = false)
324
- # Create a socket to accept connections from clients
325
- addr = Socket.pack_sockaddr_in(port, @listen_address)
326
- listen_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
327
- listen_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1) unless Kernel.is_windows?
328
- begin
329
- listen_socket.bind(addr)
330
- rescue Errno::EADDRINUSE
331
- raise "Error binding to port #{port}.\n" +
332
- "Either another application is using this port\n" +
333
- "or the operating system is being slow cleaning up.\n" +
334
- "Make sure all sockets/streams are closed in all applications,\n" +
335
- "wait 1 minute and try again."
336
- end
337
-
338
- listen_socket.listen(5)
339
-
340
- @listen_sockets << listen_socket
341
-
342
- # Start Listen Thread
343
- @listen_threads << Thread.new do
344
- begin
345
- thread_reader, thread_writer = IO.pipe
346
- @listen_pipes << thread_writer
347
- while true
348
- listen_thread_body(listen_socket, listen_write, listen_read, thread_reader)
349
- break if @cancel_threads
350
- end
351
- rescue Exception => err
352
- Logger.instance.error("Tcpip server listen thread unexpectedly died")
353
- Logger.instance.error(err.formatted)
354
- end
355
- end
356
- end
357
-
358
- def listen_thread_body(listen_socket, listen_write, listen_read, thread_reader)
359
- begin
360
- socket, address = listen_socket.accept_nonblock
361
- rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EINTR, Errno::EWOULDBLOCK
362
- read_ready, _ = IO.select([listen_socket, thread_reader])
363
- if read_ready and read_ready.include?(thread_reader)
364
- return
365
- else
366
- retry
367
- end
368
- end
369
-
370
- port, host_ip = Socket.unpack_sockaddr_in(address)
371
- hostname = ''
372
- hostname = Socket.lookup_hostname_from_ip(host_ip) if System.instance.use_dns
373
- if System.instance.acl
374
- addr = ["AF_INET", 10, "lc630", host_ip.to_s]
375
- if not System.instance.acl.allow_addr?(addr)
376
- # Reject connection
377
- Cosmos.close_socket(socket)
378
- Logger.instance.info "Tcpip server rejected connection from #{hostname}(#{host_ip}):#{port}"
379
- return
380
- end
381
- end
382
-
383
- # Configure TCP_NODELAY option
384
- socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
385
-
386
- # Accept Connection
387
- write_socket = nil
388
- read_socket = nil
389
- write_socket = socket if listen_write
390
- read_socket = socket if listen_read
391
- stream = TcpipSocketStream.new(write_socket, read_socket, @write_timeout, @read_timeout)
392
- if @raw_logger_pair
393
- stream.raw_logger_pair = @raw_logger_pair.clone
394
- stream.raw_logger_pair.start if @raw_logging_enabled
395
- end
396
-
397
- stream_protocol = @stream_protocol_class.new(*@stream_protocol_args)
398
- stream_protocol.interface = @interface if @interface
399
- stream_protocol.connect(stream)
400
-
401
- if listen_write
402
- @write_connection_callback.call(stream_protocol) if @write_connection_callback
403
- @connection_mutex.synchronize do
404
- @write_stream_protocols << [stream_protocol, hostname, host_ip, port]
405
- end
406
- end
407
- if listen_read
408
- @read_connection_callback.call(stream_protocol) if @read_connection_callback
409
- @connection_mutex.synchronize do
410
- @read_stream_protocols << [stream_protocol, hostname, host_ip, port]
411
- end
412
-
413
- # Start read thread
414
- @read_threads << Thread.new do
415
- index_to_delete = nil
416
- begin
417
- begin
418
- read_thread_body(stream_protocol)
419
- rescue Exception => err
420
- Logger.instance.error "Tcpip server read thread unexpectedly died"
421
- Logger.instance.error err.formatted
422
- end
423
- Logger.instance.info "Tcpip server lost read connection to #{hostname}(#{host_ip}):#{port}"
424
- @read_threads.delete(Thread.current)
425
-
426
- index_to_delete = nil
427
- @connection_mutex.synchronize do
428
- begin
429
- index = 0
430
- @read_stream_protocols.each do |read_stream_protocol, _, _, _|
431
- if read_stream_protocol == stream_protocol
432
- index_to_delete = index
433
- read_stream_protocol.disconnect
434
- read_stream_protocol.stream.raw_logger_pair.stop if read_stream_protocol.stream.raw_logger_pair
435
- break
436
- end
437
- index += 1
438
- end
439
- ensure
440
- if index_to_delete
441
- @read_stream_protocols.delete_at(index_to_delete)
442
- end
443
- end
444
- end
445
- rescue Exception => err
446
- Logger.instance.error "Tcpip server read thread unexpectedly died"
447
- Logger.instance.error err.formatted
448
- end
449
- end
450
- end
451
-
452
- Logger.instance.info "Tcpip server accepted connection from #{hostname}(#{host_ip}):#{port}"
453
- end
454
-
455
- def write_thread_body
456
- # Retrieve the next packet to be sent out to clients
457
- # Handles disconnected clients even when packets aren't flowing
458
- packet = nil
459
-
460
- loop do
461
- break if @cancel_threads
462
- begin
463
- packet = @write_queue.pop(true)
464
- break
465
- rescue ThreadError
466
- # Timeout waiting for send - check for dead clients
467
- indexes_to_delete = []
468
- index = 0
469
-
470
- @connection_mutex.synchronize do
471
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
472
- begin
473
- if (@write_port != @read_port)
474
- # Socket should return EWOULDBLOCK if it is still cleanly connected
475
- stream_protocol.stream.write_socket.recvfrom_nonblock(10)
476
- elsif (!stream_protocol.stream.write_socket.closed?)
477
- # Let read thread detect disconnect
478
- next
479
- end
480
-
481
- # Client has disconnected (or is invalidly sending data on the socket)
482
- Logger.instance.info "Tcpip server lost write connection to #{hostname}(#{host_ip}):#{port}"
483
- stream_protocol.disconnect
484
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
485
- indexes_to_delete.unshift(index) # Put later indexes at front of array
486
- rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError
487
- # Client has disconnected
488
- Logger.instance.info "Tcpip server lost write connection to #{hostname}(#{host_ip}):#{port}"
489
- stream_protocol.disconnect
490
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
491
- indexes_to_delete.unshift(index) # Put later indexes at front of array
492
- rescue Errno::EWOULDBLOCK
493
- # Client is still cleanly connected as far as we can tell without writing to the socket
494
- ensure
495
- index += 1
496
- end
497
- end
498
-
499
- # Delete any dead sockets
500
- indexes_to_delete.each do |index_to_delete|
501
- @write_stream_protocols.delete_at(index_to_delete)
502
- end
503
- end # connection_mutex.synchronize
504
-
505
- # Sleep until we receive a packet or for 100ms
506
- @write_mutex.synchronize do
507
- @write_condition_variable.wait(@write_mutex, 0.1)
508
- end
509
- end
510
- end
511
-
512
- packet = write_thread_hook(packet)
513
-
514
- if packet
515
- @connection_mutex.synchronize do
516
- # Send data to each client - On error drop the client
517
- indexes_to_delete = []
518
- index = 0
519
- @write_stream_protocols.each do |stream_protocol, hostname, host_ip, port|
520
- need_disconnect = false
521
- begin
522
- stream_protocol.write(packet)
523
- rescue Errno::EPIPE, Errno::ECONNABORTED, IOError, Errno::ECONNRESET
524
- # Client has normally disconnected
525
- need_disconnect = true
526
- rescue Exception => err
527
- if err.message != "Stream not connected for write_raw"
528
- Logger.instance.error "Error sending to client: #{err.class} #{err.message}"
529
- end
530
- need_disconnect = true
531
- end
532
-
533
- if need_disconnect
534
- Logger.instance.info "Tcpip server lost write connection to #{hostname}(#{host_ip}):#{port}"
535
- stream_protocol.disconnect
536
- stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
537
- indexes_to_delete.unshift(index) # Put later indexes at front of array
538
- end
539
-
540
- index += 1
541
- end
542
-
543
- # Delete any dead sockets
544
- indexes_to_delete.each do |index_to_delete|
545
- @write_stream_protocols.delete_at(index_to_delete)
546
- end
547
- end # connection_mutex.synchronize
548
- end
549
- end
550
-
551
- def write_thread_hook(packet)
552
- return packet # By default just return the packet
553
- end
554
-
555
- def read_thread_body(stream_protocol)
556
- loop do
557
- packet = stream_protocol.read
558
- return if !packet or @cancel_threads
559
-
560
- # Do work on received packet
561
- read_thread_hook(packet)
562
- end # loop do
563
- end
564
-
565
- def read_thread_hook(packet)
566
- @read_queue << packet.clone
567
- end
568
-
569
- end # class TcpipServerStream
570
-
571
- end # module Cosmos