cosmos 4.4.0 → 4.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. checksums.yaml +5 -5
  2. data/.dockerignore +2 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +6 -6
  5. data/Dockerfile +70 -0
  6. data/Manifest.txt +37 -2
  7. data/README.md +9 -0
  8. data/Rakefile +55 -5
  9. data/appveyor.yml +18 -8
  10. data/autohotkey/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  11. data/autohotkey/lib/cmd_sequence_exporter.rb +52 -0
  12. data/autohotkey/procedures/collect.rb +2 -2
  13. data/autohotkey/procedures/collect_util.rb +1 -1
  14. data/autohotkey/procedures/script_test.rb +1 -1
  15. data/autohotkey/tools/CmdSenderAHK2 +18 -0
  16. data/autohotkey/tools/cmd_extractor.ahk +11 -9
  17. data/autohotkey/tools/cmd_sender.ahk +35 -7
  18. data/autohotkey/tools/cmd_sender2.ahk +4 -0
  19. data/autohotkey/tools/cmd_sequence.ahk +22 -9
  20. data/autohotkey/tools/config_editor.ahk +4 -4
  21. data/autohotkey/tools/data_viewer.ahk +1 -1
  22. data/autohotkey/tools/limits_monitor.ahk +1 -1
  23. data/autohotkey/tools/packet_viewer.ahk +1 -1
  24. data/autohotkey/tools/script_runner.ahk +1 -1
  25. data/autohotkey/tools/test_runner2.ahk +1 -1
  26. data/autohotkey/tools/tlm_grapher.ahk +1 -1
  27. data/autohotkey/tools/tlm_grapher3.ahk +1 -1
  28. data/autohotkey/tools/tlm_viewer.ahk +1 -1
  29. data/autohotkey/tools/tlm_viewer2.ahk +1 -1
  30. data/autohotkey/tools/tlm_viewer5.ahk +1 -1
  31. data/bin/cstol_converter +1 -1
  32. data/bin/rubysloc +73 -28
  33. data/bin/xtce_converter +1 -1
  34. data/cosmos.gemspec +2 -2
  35. data/data/config/command_modifiers.yaml +16 -1
  36. data/data/config/interface_modifiers.yaml +3 -2
  37. data/data/config/param_item_modifiers.yaml +5 -0
  38. data/data/config/system.yaml +110 -23
  39. data/data/config/telemetry_modifiers.yaml +16 -1
  40. data/data/crc.txt +416 -411
  41. data/demo/Rakefile +4 -4
  42. data/demo/config/dart/Gemfile +1 -6
  43. data/demo/config/data/crc.txt +233 -232
  44. data/demo/config/system/system.txt +17 -6
  45. data/demo/config/system/system2.txt +17 -6
  46. data/demo/config/system/system_alt_ports.txt +17 -6
  47. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +4 -4
  48. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +4 -0
  49. data/demo/config/targets/INST/cmd_tlm/inst_tlm_override.txt +12 -0
  50. data/demo/config/targets/INST/lib/sim_inst.rb +2 -2
  51. data/demo/config/targets/INST/target.txt +1 -0
  52. data/demo/config/tools/handbook_creator/default_toc.xsl +59 -59
  53. data/demo/procedures/cosmos_api_test.rb +8 -8
  54. data/ext/cosmos/ext/buffered_file/buffered_file.c +2 -2
  55. data/ext/cosmos/ext/config_parser/config_parser.c +1 -2
  56. data/ext/cosmos/ext/line_graph/line_graph.c +53 -94
  57. data/ext/cosmos/ext/platform/platform.c +56 -21
  58. data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +4 -8
  59. data/ext/cosmos/ext/structure/structure.c +12 -0
  60. data/extensions/vscode/.gitignore +4 -0
  61. data/extensions/vscode/.vscode/launch.json +32 -0
  62. data/extensions/vscode/.vscode/settings.json +13 -0
  63. data/extensions/vscode/.vscode/tasks.json +79 -0
  64. data/extensions/vscode/License.txt +879 -0
  65. data/extensions/vscode/README.md +9 -0
  66. data/extensions/vscode/client/License.txt +879 -0
  67. data/extensions/vscode/client/README.md +39 -0
  68. data/extensions/vscode/client/cosmos.configuration.json +23 -0
  69. data/extensions/vscode/client/images/icon.png +0 -0
  70. data/extensions/vscode/client/package-lock.json +414 -0
  71. data/extensions/vscode/client/package.json +105 -0
  72. data/extensions/vscode/client/src/extension.ts +132 -0
  73. data/extensions/vscode/client/src/screen_preview.rb +25 -0
  74. data/extensions/vscode/client/syntaxes/cosmos.tmLanguage.json +219 -0
  75. data/extensions/vscode/client/tsconfig.json +17 -0
  76. data/extensions/vscode/package-lock.json +26 -0
  77. data/extensions/vscode/package.json +35 -0
  78. data/extensions/vscode/server/License.txt +879 -0
  79. data/extensions/vscode/server/package-lock.json +236 -0
  80. data/extensions/vscode/server/package.json +29 -0
  81. data/extensions/vscode/server/src/server.ts +59 -0
  82. data/extensions/vscode/server/tsconfig.json +16 -0
  83. data/install/Rakefile +4 -4
  84. data/install/config/dart/Gemfile +2 -7
  85. data/install/config/data/crc.txt +137 -137
  86. data/install/config/system/system.txt +17 -6
  87. data/install/config/tools/handbook_creator/default_toc.xsl +59 -59
  88. data/lib/cosmos/config/config_parser.rb +2 -10
  89. data/lib/cosmos/core_ext/class.rb +10 -0
  90. data/lib/cosmos/core_ext/time.rb +5 -3
  91. data/lib/cosmos/dart/config/boot.rb +1 -1
  92. data/lib/cosmos/dart/config/database.yml +2 -0
  93. data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
  94. data/lib/cosmos/dart/lib/dart_common.rb +12 -5
  95. data/lib/cosmos/dart/lib/dart_constants.rb +15 -0
  96. data/lib/cosmos/dart/lib/dart_decom_query.rb +5 -6
  97. data/lib/cosmos/dart/lib/dart_decommutator.rb +64 -54
  98. data/lib/cosmos/dart/lib/dart_master_query.rb +71 -0
  99. data/lib/cosmos/dart/lib/dart_reducer_worker_thread.rb +165 -134
  100. data/lib/cosmos/dart/processes/dart.rb +4 -2
  101. data/lib/cosmos/dart/processes/dart_decom_server.rb +3 -3
  102. data/lib/cosmos/dart/processes/dart_ingester.rb +38 -1
  103. data/lib/cosmos/dart/processes/dart_master.rb +44 -0
  104. data/lib/cosmos/dart/processes/dart_util.rb +115 -0
  105. data/lib/cosmos/dart/spec/dart/dart_database_cleaner_spec.rb +2 -2
  106. data/lib/cosmos/gui/qt.rb +10 -10
  107. data/lib/cosmos/gui/qt_tool.rb +17 -12
  108. data/lib/cosmos/gui/text/completion_text_edit.rb +2 -0
  109. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +22 -3
  110. data/lib/cosmos/interfaces/dart_status_interface.rb +1 -1
  111. data/lib/cosmos/interfaces/linc_interface.rb +3 -3
  112. data/lib/cosmos/interfaces/protocols/burst_protocol.rb +1 -1
  113. data/lib/cosmos/interfaces/protocols/crc_protocol.rb +1 -1
  114. data/lib/cosmos/interfaces/protocols/length_protocol.rb +5 -0
  115. data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -3
  116. data/lib/cosmos/interfaces/serial_interface.rb +7 -1
  117. data/lib/cosmos/interfaces/stream_interface.rb +1 -1
  118. data/lib/cosmos/interfaces/tcpip_server_interface.rb +16 -16
  119. data/lib/cosmos/io/io_multiplexer.rb +6 -2
  120. data/lib/cosmos/io/json_drb.rb +5 -5
  121. data/lib/cosmos/io/json_drb_object.rb +7 -2
  122. data/lib/cosmos/io/json_drb_rack.rb +25 -5
  123. data/lib/cosmos/io/json_rpc.rb +1 -1
  124. data/lib/cosmos/io/posix_serial_driver.rb +60 -22
  125. data/lib/cosmos/io/serial_driver.rb +11 -8
  126. data/lib/cosmos/io/win32_serial_driver.rb +31 -3
  127. data/lib/cosmos/packet_logs/packet_log_reader.rb +2 -2
  128. data/lib/cosmos/packets/packet.rb +9 -9
  129. data/lib/cosmos/packets/packet_config.rb +27 -9
  130. data/lib/cosmos/packets/parsers/xtce_converter.rb +10 -10
  131. data/lib/cosmos/packets/parsers/xtce_parser.rb +3 -0
  132. data/lib/cosmos/packets/structure.rb +35 -5
  133. data/lib/cosmos/packets/structure_item.rb +5 -1
  134. data/lib/cosmos/packets/telemetry.rb +7 -1
  135. data/lib/cosmos/script/api_shared.rb +18 -1
  136. data/lib/cosmos/script/extract.rb +1 -1
  137. data/lib/cosmos/script/script.rb +4 -11
  138. data/lib/cosmos/streams/serial_stream.rb +11 -6
  139. data/lib/cosmos/system/system.rb +155 -57
  140. data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +15 -0
  141. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +382 -0
  142. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +29 -318
  143. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +14 -17
  144. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +38 -331
  145. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +16 -11
  146. data/lib/cosmos/tools/cmd_tlm_server/api.rb +10 -8
  147. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +2 -2
  148. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +1 -0
  149. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +1 -1
  150. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +29 -26
  151. data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +1 -1
  152. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +5 -0
  153. data/lib/cosmos/tools/config_editor/config_editor.rb +34 -3
  154. data/lib/cosmos/tools/config_editor/config_editor_frame.rb +8 -9
  155. data/lib/cosmos/tools/config_editor/system_config_dialog.rb +158 -0
  156. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +1 -1
  157. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +1 -1
  158. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +7 -4
  159. data/lib/cosmos/tools/test_runner/test.rb +6 -3
  160. data/lib/cosmos/tools/test_runner/test_runner.rb +6 -6
  161. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +3 -3
  162. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -4
  163. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +20 -16
  164. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +21 -17
  165. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +18 -11
  166. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +17 -6
  167. data/lib/cosmos/tools/tlm_viewer/widgets/canvasdot_widget.rb +2 -0
  168. data/lib/cosmos/top_level.rb +1 -1
  169. data/lib/cosmos/utilities/ruby_lex_utils.rb +34 -30
  170. data/lib/cosmos/utilities/simulated_target.rb +1 -1
  171. data/lib/cosmos/version.rb +5 -5
  172. data/lib/cosmos/win32/excel.rb +23 -17
  173. data/run_gui_tests.bat +1 -0
  174. data/spec/core_ext/class_spec.rb +54 -0
  175. data/spec/core_ext/socket_spec.rb +1 -1
  176. data/spec/core_ext/time_spec.rb +4 -0
  177. data/spec/install/yaml_docs_spec.rb +26 -6
  178. data/spec/interfaces/linc_interface_spec.rb +1 -1
  179. data/spec/interfaces/protocols/length_protocol_spec.rb +39 -0
  180. data/spec/interfaces/serial_interface_spec.rb +1 -5
  181. data/spec/io/json_drb_rack_spec.rb +166 -0
  182. data/spec/io/json_drb_spec.rb +14 -0
  183. data/spec/io/json_rpc_spec.rb +4 -5
  184. data/spec/io/posix_serial_driver_spec.rb +81 -0
  185. data/spec/io/win32_serial_driver_spec.rb +33 -3
  186. data/spec/packet_logs/packet_log_reader_spec.rb +36 -37
  187. data/spec/packets/structure_spec.rb +52 -2
  188. data/spec/packets/telemetry_spec.rb +29 -1
  189. data/spec/script/extract_spec.rb +4 -1
  190. data/spec/system/system_spec.rb +111 -3
  191. data/spec/tools/cmd_tlm_server/api_spec.rb +12 -12
  192. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +2 -2
  193. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +4 -3
  194. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
  195. data/spec/utilities/logger_spec.rb +3 -3
  196. data/spec/utilities/message_log_spec.rb +6 -3
  197. data/tasks/gemfile_stats.rake +22 -13
  198. data/test/performance/Rakefile +4 -4
  199. data/test/performance/config/data/crc.txt +67 -48
  200. metadata +52 -11
  201. data/demo/outputs/dart/logs/README.txt +0 -1
  202. data/lib/cosmos/dart/Gemfile +0 -69
@@ -20,6 +20,7 @@ require 'drb/acl'
20
20
  require 'zip'
21
21
  require 'zip/filesystem'
22
22
  require 'bundler'
23
+ require 'thread'
23
24
 
24
25
  module Cosmos
25
26
  # System is the primary entry point into the COSMOS framework. It captures
@@ -75,11 +76,20 @@ module Cosmos
75
76
  instance_attr_reader :classificiation_banner
76
77
  # @return [String] Which hashing algorithm is in use
77
78
  instance_attr_reader :hashing_algorithm
79
+ # @return [Boolean] Allow router commanding - defaults to false
80
+ instance_attr_reader :allow_router_commanding
81
+ # @return [String] API access secret using X-Csrf-Token - defaults to SuperSecret
82
+ instance_attr_reader :x_csrf_token
83
+ # @return [Array<String>] Allowed origins in http origin header - defaults to no origin header only
84
+ instance_attr_reader :allowed_origins
85
+ # @return [Array<String>] Allowed hosts in http host header - defaults to '127.0.0.1:7777' only
86
+ instance_attr_reader :allowed_hosts
78
87
 
79
88
  # Known COSMOS ports
80
- KNOWN_PORTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER', 'REPLAY_API', 'REPLAY_PREIDENTIFIED', 'REPLAY_CMD_ROUTER', 'DART_STREAM', 'DART_DECOM']
89
+ KNOWN_PORTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER', 'REPLAY_API', 'REPLAY_PREIDENTIFIED', 'REPLAY_CMD_ROUTER', 'DART_STREAM', 'DART_DECOM', 'DART_MASTER']
90
+ API_PORTS = ['CTS_API', 'TLMVIEWER_API', 'REPLAY_API', 'DART_DECOM', 'DART_MASTER']
81
91
  # Known COSMOS hosts
82
- KNOWN_HOSTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER', 'REPLAY_API', 'REPLAY_PREIDENTIFIED', 'REPLAY_CMD_ROUTER', 'DART_STREAM', 'DART_DECOM']
92
+ KNOWN_HOSTS = ['CTS_API', 'TLMVIEWER_API', 'CTS_PREIDENTIFIED', 'CTS_CMD_ROUTER', 'REPLAY_API', 'REPLAY_PREIDENTIFIED', 'REPLAY_CMD_ROUTER', 'DART_STREAM', 'DART_DECOM', 'DART_MASTER']
83
93
  # Known COSMOS paths
84
94
  KNOWN_PATHS = ['LOGS', 'TMP', 'SAVED_CONFIG', 'TABLES', 'HANDBOOKS', 'PROCEDURES', 'SEQUENCES', 'DART_DATA', 'DART_LOGS']
85
95
  # Supported hashing algorithms
@@ -87,6 +97,7 @@ module Cosmos
87
97
 
88
98
  @@instance = nil
89
99
  @@instance_mutex = Mutex.new
100
+ @@instance_filename = nil
90
101
 
91
102
  # Create a new System object. Note, this should not be called directly but
92
103
  # you should instead use System.instance and treat this class as a
@@ -96,6 +107,7 @@ module Cosmos
96
107
  # read. Be default this is <Cosmos::USERPATH>/config/system/system.txt
97
108
  def initialize(filename = nil)
98
109
  raise "Cosmos::System created twice" unless @@instance.nil?
110
+ @@instance_filename = filename
99
111
  reset_variables(filename)
100
112
  @@instance = self
101
113
  end
@@ -195,6 +207,7 @@ module Cosmos
195
207
  @targets = {}
196
208
  # Set config to nil so things will lazy load later
197
209
  @config = nil
210
+ @meta_init_filename = nil
198
211
  @use_utc = false
199
212
  acl_list = []
200
213
  all_allowed = false
@@ -207,7 +220,7 @@ module Cosmos
207
220
  # First pass - Everything except targets
208
221
  parser.parse_file(filename) do |keyword, parameters|
209
222
  case keyword
210
- when 'AUTO_DECLARE_TARGETS', 'DECLARE_TARGET', 'DECLARE_GEM_TARGET'
223
+ when 'AUTO_DECLARE_TARGETS', 'DECLARE_TARGET', 'DECLARE_GEM_TARGET', 'DECLARE_GEM_MULTI_TARGET'
211
224
  # Will be handled by second pass
212
225
 
213
226
  when 'PORT'
@@ -215,6 +228,7 @@ module Cosmos
215
228
  parser.verify_num_parameters(2, 2, usage)
216
229
  port_name = parameters[0].to_s.upcase
217
230
  @ports[port_name] = Integer(parameters[1])
231
+ @allowed_hosts << "127.0.0.1:#{parameters[1]}" if API_PORTS.include?(port_name)
218
232
  Logger.warn("Unknown port name given: #{port_name}") unless KNOWN_PORTS.include?(port_name)
219
233
 
220
234
  when 'LISTEN_HOST', 'CONNECT_HOST'
@@ -371,6 +385,22 @@ module Cosmos
371
385
  @classificiation_banner = {'display_text' => parameters[0],
372
386
  'color' => color}
373
387
 
388
+ when 'ALLOW_ROUTER_COMMANDING'
389
+ parser.verify_num_parameters(0, 0, "#{keyword}")
390
+ @allow_router_commanding = true
391
+
392
+ when 'X_CSRF_TOKEN'
393
+ parser.verify_num_parameters(1, 1, "#{keyword} <Token>")
394
+ @x_csrf_token = ConfigParser.handle_nil(parameters[0])
395
+
396
+ when 'ALLOW_ORIGIN'
397
+ parser.verify_num_parameters(1, 1, "#{keyword} <Origin>")
398
+ @allowed_origins << parameters[0]
399
+
400
+ when 'ALLOW_HOST'
401
+ parser.verify_num_parameters(1, 1, "#{keyword} <Host:Port>")
402
+ @allowed_hosts << parameters[0]
403
+
374
404
  else
375
405
  # blank lines will have a nil keyword and should not raise an exception
376
406
  raise parser.error("Unknown keyword '#{keyword}'") if keyword
@@ -458,6 +488,19 @@ module Cosmos
458
488
  target = Target.new(target_name, substitute_name, configuration_directory, ConfigParser.handle_nil(parameters[2]), gem_dir)
459
489
  @targets[target.name] = target
460
490
 
491
+ when 'DECLARE_GEM_MULTI_TARGET'
492
+ usage = "#{keyword} <GEM NAME> <TARGET NAME> <SUBSTITUTE TARGET NAME (Optional)> <TARGET FILENAME (Optional - defaults to target.txt)>"
493
+ parser.verify_num_parameters(2, 4, usage)
494
+
495
+ target_name = parameters[1].to_s.upcase
496
+ substitute_name = nil
497
+ substitute_name = ConfigParser.handle_nil(parameters[2])
498
+ substitute_name.to_s.upcase if substitute_name
499
+ gem_dir = Gem::Specification.find_by_name(parameters[0]).gem_dir
500
+ gem_dir = File.join(gem_dir, target_name)
501
+ target = Target.new(target_name, substitute_name, configuration_directory, ConfigParser.handle_nil(parameters[3]), gem_dir)
502
+ @targets[target.name] = target
503
+
461
504
  end # case keyword
462
505
  end # parser.parse_file
463
506
 
@@ -476,48 +519,65 @@ module Cosmos
476
519
  # configuration. Pass nil to load the default configuration.
477
520
  # @return [String, Exception/nil] The actual configuration loaded
478
521
  def load_configuration(name = nil)
479
- unless @config
480
- # Ensure packets have been lazy loaded
481
- System.commands
482
- end
522
+ # Ensure packets have been lazy loaded
523
+ load_packets() unless @config
483
524
 
484
- if name && @config
485
- # Make sure they're requesting something other than the current
486
- # configuration.
487
- if name != @config.name
488
- # If they want the initial configuration we can just swap out the
489
- # current configuration without doing any file processing
490
- if name == @initial_config.name
491
- update_config(@initial_config)
492
- else
493
- # Look for the requested configuration in the saved configurations
494
- configuration = find_configuration(name)
495
- if configuration
496
- # We found the configuration requested. Reprocess the system.txt
497
- # and reload the packets
498
- begin
499
- unless File.directory?(configuration)
500
- # Zip file configuration so unzip and reset configuration path
501
- configuration = unzip(configuration)
525
+ @@instance_mutex.synchronize do
526
+ if @config_blacklist[name]
527
+ Logger.warn "Ignoring failed config #{name}"
528
+ update_config(@initial_config)
529
+ return @config.name, RuntimeError.new("Ignoring failed config #{name}")
530
+ end
531
+
532
+ if name && @config
533
+ # Make sure they're requesting something other than the current
534
+ # configuration.
535
+ if name != @config.name
536
+ # If they want the initial configuration we can just swap out the
537
+ # current configuration without doing any file processing
538
+ if name == @initial_config.name
539
+ Logger.info "Switching to initial configuration: #{name}"
540
+ update_config(@initial_config)
541
+ else
542
+ # Look for the requested configuration in the saved configurations
543
+ configuration = find_configuration(name)
544
+ if configuration
545
+ # We found the configuration requested. Reprocess the system.txt
546
+ # and reload the packets
547
+ begin
548
+ unless File.directory?(configuration)
549
+ # Zip file configuration so unzip and reset configuration path
550
+ configuration = unzip(configuration)
551
+ end
552
+
553
+ Logger.info "Switching to configuration: #{name}"
554
+ process_file(File.join(configuration, 'system.txt'), configuration)
555
+ load_packets(name, false)
556
+ rescue Exception => error
557
+ # Failed to load - Restore initial
558
+ @config_blacklist[name] = true # Prevent wasting time trying to load the bad configuration again
559
+ Logger.error "Problem loading configuration from #{configuration}: #{error.class}:#{error.message}\n#{error.backtrace.join("\n")}\n"
560
+ Logger.info "Switching to initial configuration: #{@initial_config.name}"
561
+ update_config(@initial_config)
562
+ return @config.name, error
502
563
  end
503
- process_file(File.join(configuration, 'system.txt'), configuration)
504
- load_packets(name)
505
- rescue Exception => error
506
- # Failed to load - Restore initial
564
+ else
565
+ # We couldn't find the configuration request. Reload the
566
+ # initial configuration
567
+ Logger.error "Unable to find configuration: #{name}"
568
+ Logger.info "Switching to initial configuration: #{@initial_config.name}"
507
569
  update_config(@initial_config)
508
- return @config.name, error
570
+ return @config.name, RuntimeError.new("Unable to find configuration: #{name}")
509
571
  end
510
- else
511
- # We couldn't find the configuration request. Reload the
512
- # initial configuration
513
- update_config(@initial_config)
514
572
  end
515
573
  end
574
+ else
575
+ Logger.info "Switching to initial configuration: #{@initial_config.name}"
576
+ update_config(@initial_config)
516
577
  end
517
- else
518
- update_config(@initial_config)
578
+
579
+ return @config.name, nil
519
580
  end
520
- return @config.name, nil
521
581
  end
522
582
 
523
583
  # (see #load_configuration)
@@ -530,7 +590,6 @@ module Cosmos
530
590
  # @param filename [String] Path to system.txt config file to process. Defaults to config/system/system.txt
531
591
  def reset_variables(filename = nil)
532
592
  @targets = {}
533
- @targets['UNKNOWN'] = Target.new('UNKNOWN')
534
593
  @config = nil
535
594
  @commands = nil
536
595
  @telemetry = nil
@@ -557,21 +616,22 @@ module Cosmos
557
616
  @ports['REPLAY_API'] = 7877
558
617
  @ports['REPLAY_PREIDENTIFIED'] = 7879
559
618
  @ports['REPLAY_CMD_ROUTER'] = 7880
560
- @ports['DART_DECOM'] = 8777
561
- @ports['DART_STREAM'] = 8779
619
+
620
+ @ports['DART_STREAM'] = 8777
621
+ @ports['DART_DECOM'] = 8779
622
+ @ports['DART_MASTER'] = 8780
562
623
 
563
624
  @listen_hosts = {}
564
625
  @listen_hosts['CTS_API'] = '127.0.0.1'
565
626
  @listen_hosts['TLMVIEWER_API'] = '127.0.0.1'
566
- # Localhost would be more secure but historically these are open to allow for chaining servers by default
567
- @listen_hosts['CTS_PREIDENTIFIED'] = '0.0.0.0'
568
- @listen_hosts['CTS_CMD_ROUTER'] = '0.0.0.0'
627
+ @listen_hosts['CTS_PREIDENTIFIED'] = '127.0.0.1'
628
+ @listen_hosts['CTS_CMD_ROUTER'] = '127.0.0.1'
569
629
  @listen_hosts['REPLAY_API'] = '127.0.0.1'
570
- # Localhost would be more secure but historically these are open to allow for chaining servers by default
571
- @listen_hosts['REPLAY_PREIDENTIFIED'] = '0.0.0.0'
572
- @listen_hosts['REPLAY_CMD_ROUTER'] = '0.0.0.0'
573
- @listen_hosts['DART_STREAM'] = '0.0.0.0'
574
- @listen_hosts['DART_DECOM'] = '0.0.0.0'
630
+ @listen_hosts['REPLAY_PREIDENTIFIED'] = '127.0.0.1'
631
+ @listen_hosts['REPLAY_CMD_ROUTER'] = '127.0.0.1'
632
+ @listen_hosts['DART_STREAM'] = '127.0.0.1'
633
+ @listen_hosts['DART_DECOM'] = '127.0.0.1'
634
+ @listen_hosts['DART_MASTER'] = '127.0.0.1'
575
635
 
576
636
  @connect_hosts = {}
577
637
  @connect_hosts['CTS_API'] = '127.0.0.1'
@@ -583,6 +643,7 @@ module Cosmos
583
643
  @connect_hosts['REPLAY_CMD_ROUTER'] = '127.0.0.1'
584
644
  @connect_hosts['DART_STREAM'] = '127.0.0.1'
585
645
  @connect_hosts['DART_DECOM'] = '127.0.0.1'
646
+ @connect_hosts['DART_MASTER'] = '127.0.0.1'
586
647
 
587
648
  @paths = {}
588
649
  @paths['LOGS'] = File.join(USERPATH, 'outputs', 'logs')
@@ -595,6 +656,11 @@ module Cosmos
595
656
  @paths['DART_DATA'] = File.join(USERPATH, 'outputs', 'dart', 'data')
596
657
  @paths['DART_LOGS'] = File.join(USERPATH, 'outputs', 'dart', 'logs')
597
658
 
659
+ @allow_router_commanding = false
660
+ @x_csrf_token = 'SuperSecret'
661
+ @allowed_origins = []
662
+ @allowed_hosts = ['127.0.0.1:7777', '127.0.0.1:7778', '127.0.0.1:7877', '127.0.0.1:8779', '127.0.0.1:8780']
663
+
598
664
  unless filename
599
665
  system_arg = false
600
666
  ARGV.each do |arg|
@@ -611,10 +677,11 @@ module Cosmos
611
677
 
612
678
  @initial_filename = filename
613
679
  @initial_config = nil
680
+ @config_blacklist = {}
614
681
  end
615
682
 
616
683
  # Reset variables and load packets
617
- def reset(filename = nil)
684
+ def reset(filename = @@instance_filename)
618
685
  reset_variables(filename)
619
686
  load_packets()
620
687
  end
@@ -689,11 +756,31 @@ module Cosmos
689
756
  Bundler.load.specs.each do |spec|
690
757
  spec_name_split = spec.name.split('-')
691
758
  if spec_name_split.length > 1 && (spec_name_split[0] == 'cosmos')
692
- # Filter to just targets and not tools and other extensions
693
- if File.exist?(File.join(spec.gem_dir, 'cmd_tlm'))
694
- target_name = spec_name_split[1..-1].join('-').to_s.upcase
695
- target = Target.new(target_name, nil, nil, nil, spec.gem_dir)
696
- @targets[target.name] = target
759
+ # search for multiple targets packaged in a single gem
760
+ dirs = []
761
+ Dir.foreach(spec.gem_dir) { |dir_filename| dirs << dir_filename }
762
+ dirs.sort!
763
+ dirs.each do |dir_filename|
764
+ if dir_filename == "."
765
+ # check the base directory
766
+ curr_dir = spec.gem_dir
767
+ target_name = spec_name_split[1..-1].join('-').to_s.upcase
768
+ else
769
+ #check for targets in other directories 1 level deep
770
+ next if dir_filename[0] == '.' #skip dot directories and ".."
771
+ next if dir_filename != dir_filename.upcase #skip non uppercase directories
772
+ curr_dir = File.join(spec.gem_dir, dir_filename)
773
+ target_name = dir_filename
774
+ end
775
+ # check for the cmd_tlm directory - if it has it, then we have found a target
776
+ if File.directory?(File.join(curr_dir,'cmd_tlm'))
777
+ # If any of the targets original directory name matches the
778
+ # current directory then it must have been already processed by
779
+ # DECLARE_TARGET so we skip it.
780
+ next if @targets.select {|name, target| target.original_name == target_name }.length > 0
781
+ target = Target.new(target_name,nil, nil, nil, spec.gem_dir)
782
+ @targets[target.name] = target
783
+ end
697
784
  end
698
785
  end
699
786
  end
@@ -722,9 +809,10 @@ module Cosmos
722
809
  configuration = find_configuration(@config.name)
723
810
  configuration = File.join(@paths['SAVED_CONFIG'], File.build_timestamped_filename([@config.name], '.zip')) unless configuration
724
811
  unless File.exist?(configuration)
812
+ configuration_tmp = File.join(@paths['SAVED_CONFIG'], File.build_timestamped_filename(['tmp_' + @config.name], '.zip.tmp'))
725
813
  begin
726
814
  Zip.continue_on_exists_proc = true
727
- Zip::File.open(configuration, Zip::File::CREATE) do |zipfile|
815
+ Zip::File.open(configuration_tmp, Zip::File::CREATE) do |zipfile|
728
816
  zip_file_path = File.basename(configuration, ".zip")
729
817
  zipfile.mkdir zip_file_path
730
818
 
@@ -756,6 +844,7 @@ module Cosmos
756
844
  end
757
845
  end
758
846
  end
847
+ File.rename(configuration_tmp, configuration)
759
848
  File.chmod(0444, configuration) # Mark readonly
760
849
  rescue Exception => error
761
850
  Logger.error "Problem saving configuration to #{configuration}: #{error.class}:#{error.message}\n#{error.backtrace.join("\n")}\n"
@@ -764,7 +853,7 @@ module Cosmos
764
853
  end
765
854
  end
766
855
 
767
- def load_packets(configuration_name = nil)
856
+ def load_packets_internal(configuration_name = nil)
768
857
  # Determine hashing over all targets cmd_tlm files
769
858
  cmd_tlm_files = []
770
859
  additional_data = ''
@@ -785,7 +874,6 @@ module Cosmos
785
874
  # Only use at most, 32 characters of the hex
786
875
  hash_string = hash_string[-32..-1] if hash_string.length >= 32
787
876
 
788
-
789
877
  # Build filename for marshal file
790
878
  marshal_filename = File.join(@paths['TMP'], 'marshal_' << hash_string << '.bin')
791
879
 
@@ -831,6 +919,16 @@ module Cosmos
831
919
  save_configuration()
832
920
  end
833
921
 
922
+ def load_packets(configuration_name = nil, take_mutex = true)
923
+ if take_mutex
924
+ @@instance_mutex.synchronize do
925
+ load_packets_internal(configuration_name)
926
+ end
927
+ else
928
+ load_packets_internal(configuration_name)
929
+ end
930
+ end
931
+
834
932
  def setup_system_meta
835
933
  # Ensure SYSTEM META is defined and defined correctly
836
934
  begin
@@ -42,6 +42,9 @@ module Cosmos
42
42
  def paint(painter, option, index)
43
43
  packet_item, _, _ = @widgets[index.row]
44
44
  if index.column == 1 and packet_item and packet_item.states
45
+ painter.save
46
+ option = Qt::StyleOptionViewItemV4.new(option)
47
+ initStyleOption(option, index)
45
48
  # This code simply draws the current combo box text inside a button to
46
49
  # give the user an idea that they have to click it to activate it
47
50
  opt = Qt::StyleOptionButton.new
@@ -49,6 +52,18 @@ module Cosmos
49
52
  opt.text = @table.item(index.row, index.column).text.to_s
50
53
  Qt::Application.style.drawControl(Qt::Style::CE_PushButton, opt, painter)
51
54
  opt.dispose
55
+ painter.restore
56
+ # Not sure why but once we re-implement paint() the word wrapping
57
+ # doesn't work when we simply call super(painter, option, index)
58
+ # Thus we implement this to support word wrapping on the description
59
+ elsif index.column == 4
60
+ painter.save
61
+ option = Qt::StyleOptionViewItemV4.new(option)
62
+ initStyleOption(option, index)
63
+ option.text = index.data().toString()
64
+ option.features = Qt::StyleOptionViewItemV2::WrapText
65
+ self.parent().style().drawControl(Qt::Style.CE_ItemViewItem, option, painter)
66
+ painter.restore
52
67
  else
53
68
  super(painter, option, index)
54
69
  end