cosmos 4.4.1-java → 4.5.2-java

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 (160) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_v4.yml +33 -0
  3. data/Dockerfile +10 -4
  4. data/Gemfile +1 -1
  5. data/Manifest.txt +26 -2
  6. data/README.md +4 -1
  7. data/Rakefile +33 -27
  8. data/autohotkey/tools/cmd_extractor.ahk +11 -9
  9. data/autohotkey/tools/cmd_sender.ahk +1 -1
  10. data/autohotkey/tools/cmd_sequence.ahk +1 -1
  11. data/autohotkey/tools/data_viewer.ahk +1 -1
  12. data/autohotkey/tools/limits_monitor.ahk +1 -1
  13. data/autohotkey/tools/packet_viewer.ahk +1 -1
  14. data/autohotkey/tools/script_runner.ahk +1 -1
  15. data/autohotkey/tools/test_runner2.ahk +1 -1
  16. data/autohotkey/tools/tlm_grapher.ahk +1 -1
  17. data/autohotkey/tools/tlm_grapher3.ahk +1 -1
  18. data/autohotkey/tools/tlm_viewer.ahk +1 -1
  19. data/autohotkey/tools/tlm_viewer2.ahk +1 -1
  20. data/autohotkey/tools/tlm_viewer5.ahk +1 -1
  21. data/bin/rubysloc +73 -28
  22. data/bin/xtce_converter +1 -1
  23. data/cosmos.gemspec +6 -12
  24. data/data/config/interface_modifiers.yaml +3 -2
  25. data/data/config/system.yaml +81 -24
  26. data/data/crc.txt +435 -435
  27. data/demo/Rakefile +4 -4
  28. data/demo/config/data/crc.txt +250 -250
  29. data/demo/config/system/system.txt +15 -7
  30. data/demo/config/system/system2.txt +15 -7
  31. data/demo/config/system/system_alt_ports.txt +15 -7
  32. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -1
  33. data/demo/config/tools/handbook_creator/default_toc.xsl +59 -59
  34. data/ext/cosmos/ext/buffered_file/buffered_file.c +2 -2
  35. data/ext/cosmos/ext/config_parser/config_parser.c +1 -2
  36. data/ext/cosmos/ext/line_graph/line_graph.c +53 -94
  37. data/ext/cosmos/ext/packet/packet.c +0 -6
  38. data/ext/cosmos/ext/platform/platform.c +56 -21
  39. data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +4 -8
  40. data/ext/cosmos/ext/structure/structure.c +12 -0
  41. data/extensions/vscode/.gitignore +4 -0
  42. data/extensions/vscode/.vscode/launch.json +32 -0
  43. data/extensions/vscode/.vscode/settings.json +13 -0
  44. data/extensions/vscode/.vscode/tasks.json +79 -0
  45. data/extensions/vscode/License.txt +879 -0
  46. data/extensions/vscode/README.md +9 -0
  47. data/extensions/vscode/client/License.txt +879 -0
  48. data/extensions/vscode/client/README.md +39 -0
  49. data/extensions/vscode/client/cosmos.configuration.json +23 -0
  50. data/extensions/vscode/client/images/icon.png +0 -0
  51. data/extensions/vscode/client/package-lock.json +414 -0
  52. data/extensions/vscode/client/package.json +105 -0
  53. data/extensions/vscode/client/src/extension.ts +132 -0
  54. data/extensions/vscode/client/src/screen_preview.rb +25 -0
  55. data/extensions/vscode/client/syntaxes/cosmos.tmLanguage.json +219 -0
  56. data/extensions/vscode/client/tsconfig.json +17 -0
  57. data/extensions/vscode/package-lock.json +26 -0
  58. data/extensions/vscode/package.json +35 -0
  59. data/extensions/vscode/server/License.txt +879 -0
  60. data/extensions/vscode/server/package-lock.json +236 -0
  61. data/extensions/vscode/server/package.json +29 -0
  62. data/extensions/vscode/server/src/server.ts +59 -0
  63. data/extensions/vscode/server/tsconfig.json +16 -0
  64. data/install/Rakefile +4 -4
  65. data/install/config/data/crc.txt +145 -145
  66. data/install/config/system/system.txt +15 -7
  67. data/install/config/tools/handbook_creator/default_toc.xsl +59 -59
  68. data/lib/cosmos/config/config_parser.rb +2 -10
  69. data/lib/cosmos/core_ext/class.rb +10 -0
  70. data/lib/cosmos/core_ext/time.rb +5 -3
  71. data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
  72. data/lib/cosmos/dart/lib/dart_common.rb +3 -3
  73. data/lib/cosmos/dart/lib/dart_decommutator.rb +4 -4
  74. data/lib/cosmos/dart/processes/dart_decom_server.rb +1 -1
  75. data/lib/cosmos/dart/processes/dart_master.rb +1 -1
  76. data/lib/cosmos/dart/spec/dart/dart_database_cleaner_spec.rb +2 -2
  77. data/lib/cosmos/gui/qt.rb +10 -10
  78. data/lib/cosmos/gui/qt_tool.rb +17 -12
  79. data/lib/cosmos/gui/text/completion_text_edit.rb +2 -0
  80. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +1 -1
  81. data/lib/cosmos/interfaces/dart_status_interface.rb +1 -1
  82. data/lib/cosmos/interfaces/linc_interface.rb +3 -3
  83. data/lib/cosmos/interfaces/protocols/burst_protocol.rb +1 -1
  84. data/lib/cosmos/interfaces/protocols/crc_protocol.rb +1 -1
  85. data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -3
  86. data/lib/cosmos/interfaces/serial_interface.rb +7 -1
  87. data/lib/cosmos/interfaces/stream_interface.rb +1 -1
  88. data/lib/cosmos/interfaces/tcpip_server_interface.rb +16 -16
  89. data/lib/cosmos/io/io_multiplexer.rb +6 -2
  90. data/lib/cosmos/io/json_drb.rb +3 -11
  91. data/lib/cosmos/io/json_drb_object.rb +7 -2
  92. data/lib/cosmos/io/json_drb_rack.rb +25 -5
  93. data/lib/cosmos/io/json_rpc.rb +1 -1
  94. data/lib/cosmos/io/posix_serial_driver.rb +60 -22
  95. data/lib/cosmos/io/serial_driver.rb +11 -8
  96. data/lib/cosmos/io/win32_serial_driver.rb +8 -1
  97. data/lib/cosmos/packets/packet.rb +8 -8
  98. data/lib/cosmos/packets/packet_config.rb +1 -1
  99. data/lib/cosmos/packets/packet_item_limits.rb +2 -14
  100. data/lib/cosmos/packets/parsers/xtce_converter.rb +10 -10
  101. data/lib/cosmos/packets/parsers/xtce_parser.rb +3 -0
  102. data/lib/cosmos/packets/structure.rb +18 -5
  103. data/lib/cosmos/packets/structure_item.rb +4 -21
  104. data/lib/cosmos/script/api_shared.rb +18 -1
  105. data/lib/cosmos/script/extract.rb +1 -1
  106. data/lib/cosmos/script/script.rb +4 -11
  107. data/lib/cosmos/streams/serial_stream.rb +11 -6
  108. data/lib/cosmos/system/system.rb +47 -13
  109. data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +15 -0
  110. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +25 -3
  111. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +7 -0
  112. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +0 -5
  113. data/lib/cosmos/tools/cmd_tlm_server/api.rb +10 -8
  114. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +2 -2
  115. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +1 -1
  116. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +29 -26
  117. data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +1 -1
  118. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +5 -0
  119. data/lib/cosmos/tools/config_editor/config_editor.rb +1 -1
  120. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +1 -1
  121. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +1 -1
  122. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +5 -2
  123. data/lib/cosmos/tools/test_runner/test.rb +1 -1
  124. data/lib/cosmos/tools/test_runner/test_runner.rb +4 -4
  125. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +3 -3
  126. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -4
  127. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +3 -3
  128. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +1 -1
  129. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +2 -2
  130. data/lib/cosmos/tools/tlm_viewer/widgets/canvasdot_widget.rb +2 -0
  131. data/lib/cosmos/top_level.rb +1 -1
  132. data/lib/cosmos/utilities/simulated_target.rb +1 -1
  133. data/lib/cosmos/version.rb +5 -5
  134. data/make_gems.sh +1 -1
  135. data/spec/core_ext/class_spec.rb +54 -0
  136. data/spec/core_ext/time_spec.rb +4 -0
  137. data/spec/gui/qt_spec.rb +1 -1
  138. data/spec/gui/utilities/script_module_gui_spec.rb +1 -1
  139. data/spec/interfaces/linc_interface_spec.rb +1 -1
  140. data/spec/interfaces/serial_interface_spec.rb +1 -5
  141. data/spec/io/json_drb_rack_spec.rb +166 -0
  142. data/spec/io/json_rpc_spec.rb +4 -5
  143. data/spec/io/posix_serial_driver_spec.rb +87 -0
  144. data/spec/io/win32_serial_driver_spec.rb +17 -1
  145. data/spec/packet_logs/packet_log_reader_spec.rb +34 -35
  146. data/spec/packets/packet_item_limits_spec.rb +6 -33
  147. data/spec/packets/structure_item_spec.rb +3 -21
  148. data/spec/script/extract_spec.rb +4 -1
  149. data/spec/system/system_spec.rb +109 -1
  150. data/spec/tools/cmd_tlm_server/api_spec.rb +12 -12
  151. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +2 -2
  152. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +4 -3
  153. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
  154. data/spec/top_level/top_level_spec.rb +2 -2
  155. data/spec/utilities/logger_spec.rb +3 -3
  156. data/test/performance/Rakefile +4 -4
  157. data/test/performance/config/data/crc.txt +67 -48
  158. metadata +53 -9
  159. data/.coveralls.yml +0 -1
  160. data/.travis.yml +0 -16
@@ -76,9 +76,18 @@ module Cosmos
76
76
  instance_attr_reader :classificiation_banner
77
77
  # @return [String] Which hashing algorithm is in use
78
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
79
87
 
80
88
  # Known COSMOS ports
81
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']
82
91
  # Known COSMOS hosts
83
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']
84
93
  # Known COSMOS paths
@@ -88,6 +97,7 @@ module Cosmos
88
97
 
89
98
  @@instance = nil
90
99
  @@instance_mutex = Mutex.new
100
+ @@instance_filename = nil
91
101
 
92
102
  # Create a new System object. Note, this should not be called directly but
93
103
  # you should instead use System.instance and treat this class as a
@@ -97,6 +107,7 @@ module Cosmos
97
107
  # read. Be default this is <Cosmos::USERPATH>/config/system/system.txt
98
108
  def initialize(filename = nil)
99
109
  raise "Cosmos::System created twice" unless @@instance.nil?
110
+ @@instance_filename = filename
100
111
  reset_variables(filename)
101
112
  @@instance = self
102
113
  end
@@ -217,6 +228,7 @@ module Cosmos
217
228
  parser.verify_num_parameters(2, 2, usage)
218
229
  port_name = parameters[0].to_s.upcase
219
230
  @ports[port_name] = Integer(parameters[1])
231
+ @allowed_hosts << "127.0.0.1:#{parameters[1]}" if API_PORTS.include?(port_name)
220
232
  Logger.warn("Unknown port name given: #{port_name}") unless KNOWN_PORTS.include?(port_name)
221
233
 
222
234
  when 'LISTEN_HOST', 'CONNECT_HOST'
@@ -373,6 +385,22 @@ module Cosmos
373
385
  @classificiation_banner = {'display_text' => parameters[0],
374
386
  'color' => color}
375
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
+
376
404
  else
377
405
  # blank lines will have a nil keyword and should not raise an exception
378
406
  raise parser.error("Unknown keyword '#{keyword}'") if keyword
@@ -521,7 +549,7 @@ module Cosmos
521
549
  # Zip file configuration so unzip and reset configuration path
522
550
  configuration = unzip(configuration)
523
551
  end
524
-
552
+
525
553
  Logger.info "Switching to configuration: #{name}"
526
554
  process_file(File.join(configuration, 'system.txt'), configuration)
527
555
  load_packets(name, false)
@@ -547,7 +575,7 @@ module Cosmos
547
575
  Logger.info "Switching to initial configuration: #{@initial_config.name}"
548
576
  update_config(@initial_config)
549
577
  end
550
-
578
+
551
579
  return @config.name, nil
552
580
  end
553
581
  end
@@ -596,16 +624,14 @@ module Cosmos
596
624
  @listen_hosts = {}
597
625
  @listen_hosts['CTS_API'] = '127.0.0.1'
598
626
  @listen_hosts['TLMVIEWER_API'] = '127.0.0.1'
599
- # Localhost would be more secure but historically these are open to allow for chaining servers by default
600
- @listen_hosts['CTS_PREIDENTIFIED'] = '0.0.0.0'
601
- @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'
602
629
  @listen_hosts['REPLAY_API'] = '127.0.0.1'
603
- # Localhost would be more secure but historically these are open to allow for chaining servers by default
604
- @listen_hosts['REPLAY_PREIDENTIFIED'] = '0.0.0.0'
605
- @listen_hosts['REPLAY_CMD_ROUTER'] = '0.0.0.0'
606
- @listen_hosts['DART_STREAM'] = '0.0.0.0'
607
- @listen_hosts['DART_DECOM'] = '0.0.0.0'
608
- @listen_hosts['DART_MASTER'] = '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'
609
635
 
610
636
  @connect_hosts = {}
611
637
  @connect_hosts['CTS_API'] = '127.0.0.1'
@@ -630,6 +656,11 @@ module Cosmos
630
656
  @paths['DART_DATA'] = File.join(USERPATH, 'outputs', 'dart', 'data')
631
657
  @paths['DART_LOGS'] = File.join(USERPATH, 'outputs', 'dart', 'logs')
632
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
+
633
664
  unless filename
634
665
  system_arg = false
635
666
  ARGV.each do |arg|
@@ -650,7 +681,7 @@ module Cosmos
650
681
  end
651
682
 
652
683
  # Reset variables and load packets
653
- def reset(filename = nil)
684
+ def reset(filename = @@instance_filename)
654
685
  reset_variables(filename)
655
686
  load_packets()
656
687
  end
@@ -961,7 +992,10 @@ module Cosmos
961
992
  cmd_meta.disabled = true
962
993
  tlm_meta = @telemetry.packet('SYSTEM', 'META')
963
994
  tlm_meta.sorted_items.each do |item|
964
- next if item.name.include?("RECEIVED") # Tlm only items
995
+ # Ignore reserved items as these are all DERIVED and thus will throw an exception
996
+ # in CommandSender since they don't have write conversions due to:
997
+ # commands.build_cmd -> packet.restore_defaults -> packet.write_item
998
+ next if Packet::RESERVED_ITEM_NAMES.include?(item.name)
965
999
  cmd_meta.define(item.clone)
966
1000
  end
967
1001
  @config.commands['SYSTEM'] ||= {}
@@ -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
@@ -67,7 +67,7 @@ module Cosmos
67
67
  # @return [Hash] Hash keyed by parameter name with String formatted value
68
68
  def params_text(raw = false)
69
69
  params = {}
70
- Qt.execute_in_main_thread do
70
+ Qt.execute_in_main_thread do
71
71
  @param_widgets.each do |packet_item, value_item, state_value_item|
72
72
  text = value_item.text
73
73
  text = state_value_item.text if state_value_item && (text == MANUALLY or raw)
@@ -197,7 +197,7 @@ module Cosmos
197
197
  end
198
198
  end
199
199
 
200
- private
200
+ private
201
201
 
202
202
  def get_params(show_ignored)
203
203
  params = {}
@@ -322,7 +322,7 @@ module Cosmos
322
322
  value_text = "0x" + value_text.simple_formatted
323
323
  # Add quotes around STRING or BLOCK defaults so they are interpreted correctly
324
324
  elsif (packet_item.data_type == :STRING or packet_item.data_type == :BLOCK)
325
- value_text = "'#{packet_item.default}'"
325
+ value_text = "'#{value_text}'"
326
326
  end
327
327
  value_item = Qt::TableWidgetItem.new(value_text)
328
328
  value_item.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
@@ -338,6 +338,14 @@ module Cosmos
338
338
  if item.column == 1
339
339
  if packet_item.states
340
340
  value = packet_item.states[value_item.text]
341
+ if packet_item.hazardous && packet_item.hazardous.key?(value_item.text)
342
+ desc = packet_item.hazardous[value]
343
+ # Hazardous states aren't required to have a description so use the item description
344
+ desc = packet_item.description unless desc
345
+ @table.item(item.row, 4).setText("(Hazardous) #{desc}")
346
+ else
347
+ @table.item(item.row, 4).setText(packet_item.description)
348
+ end
341
349
  @table.blockSignals(true)
342
350
  if CmdParams.states_in_hex && value.kind_of?(Integer)
343
351
  state_value_item.setText(sprintf("0x%X", value))
@@ -351,10 +359,24 @@ module Cosmos
351
359
  @table.item(item.row, 1).setText(MANUALLY)
352
360
  @table.blockSignals(false)
353
361
  end
362
+ calculate_height()
354
363
  emit modified()
355
364
  end
365
+ calculate_height()
366
+ end
367
+
368
+ def calculate_height
356
369
  @table.resizeColumnsToContents()
357
370
  @table.resizeRowsToContents()
371
+ height = @table.horizontalHeader.height + 2 # 2 = Header frame?
372
+ @table.rowCount.times do |i|
373
+ # TODO: rowHeight does not reflect word wrapping ... it's always 37
374
+ height += @table.rowHeight(i)
375
+ # NOTE: Checking the fontMetrics boundingRect also does not refect word wrapping
376
+ # e.g. Cosmos.getFontMetrics(@table.font).boundingRect(@table.item(x,y).text).height
377
+ end
378
+ @table.setMaximumHeight(height)
379
+ @table.setMinimumHeight(height)
358
380
  end
359
381
  end
360
382
  end
@@ -491,6 +491,13 @@ module Cosmos
491
491
  packet_name = @cmd_select.text
492
492
  if target_name && packet_name
493
493
  packet = System.commands.packet(target_name, packet_name)
494
+ # Directly update packet description ... safe because always in GUI thread
495
+ hazardous, _ = System.commands.cmd_hazardous?(target_name, packet_name)
496
+ if hazardous
497
+ @description.text = "(Hazardous) #{packet.description}"
498
+ else
499
+ @description.text = packet.description
500
+ end
494
501
  table = @cmd_params.update_cmd_params(packet, show_ignored: checked)
495
502
  @table_layout.addWidget(table, 500) if table
496
503
  end
@@ -56,11 +56,6 @@ module Cosmos
56
56
 
57
57
  def add_table(table)
58
58
  return unless table
59
- table.setSizePolicy(Qt::SizePolicy.Minimum, Qt::SizePolicy.Minimum)
60
- table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
61
- table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
62
- table.setFixedSize(table.horizontalHeader.length + table.verticalHeader.width,
63
- 2 + table.verticalHeader.length + table.horizontalHeader.height)
64
59
  @table_layout.addWidget(table)
65
60
  end
66
61
 
@@ -591,14 +591,16 @@ module Cosmos
591
591
  end
592
592
 
593
593
  # Update current value table
594
- cvt_packet.buffer = packet.buffer(false)
595
- cvt_packet.received_time = received_time
596
-
597
- # The interface does the following line, but I don't think inject_tlm should because it could confuse the interface
598
- target.tlm_cnt += 1
599
- packet.received_count += 1
600
- cvt_packet.received_count += 1
601
- CmdTlmServer.instance.identified_packet_callback(packet)
594
+ cvt_packet.synchronize do
595
+ cvt_packet.buffer = packet.buffer(false)
596
+ cvt_packet.received_time = received_time
597
+
598
+ # The interface does the following line, but I don't think inject_tlm should because it could confuse the interface
599
+ target.tlm_cnt += 1
600
+ packet.received_count += 1
601
+ cvt_packet.received_count += 1
602
+ CmdTlmServer.instance.identified_packet_callback(cvt_packet)
603
+ end
602
604
 
603
605
  # Find the interface for this target
604
606
  interface = target.interface
@@ -201,9 +201,9 @@ module Cosmos
201
201
  @json_drb.method_whitelist = @api_whitelist
202
202
  begin
203
203
  if @mode == :CMD_TLM_SERVER
204
- @json_drb.start_service(System.listen_hosts['CTS_API'], System.ports['CTS_API'], self)
204
+ @json_drb.start_service(System.listen_hosts['CTS_API'], System.ports['CTS_API'], self, 1000, System)
205
205
  else
206
- @json_drb.start_service(System.listen_hosts['REPLAY_API'], System.ports['REPLAY_API'], self)
206
+ @json_drb.start_service(System.listen_hosts['REPLAY_API'], System.ports['REPLAY_API'], self, 1000, System)
207
207
  end
208
208
  rescue Exception
209
209
  # Call packet_logging shutdown here to explicitly kill the logging
@@ -96,7 +96,7 @@ module Cosmos
96
96
  button_layout.addWidget(button, location[0], location[1])
97
97
  button.connect(SIGNAL('clicked()')) do
98
98
  begin
99
- CmdTlmServer.instance.send(method, 'ALL')
99
+ CmdTlmServer.instance.public_send(method, 'ALL')
100
100
  rescue Exception => error
101
101
  statusBar.showMessage(error.message)
102
102
  end
@@ -148,51 +148,54 @@ module Cosmos
148
148
  if packet.identified?
149
149
  begin
150
150
  # Preidentifed packet - place it into the current value table
151
- identified_packet = System.telemetry.update!(packet.target_name,
152
- packet.packet_name,
153
- packet.buffer)
151
+ identified_packet = System.telemetry.packet(packet.target_name, packet.packet_name)
154
152
  rescue RuntimeError
155
153
  # Packet identified but we don't know about it
156
154
  # Clear packet_name and target_name and try to identify
157
155
  Logger.warn "Received unknown identified telemetry: #{packet.target_name} #{packet.packet_name}"
158
156
  packet.target_name = nil
159
157
  packet.packet_name = nil
160
- identified_packet = System.telemetry.identify!(packet.buffer,
161
- @interface.target_names)
158
+ identified_packet = System.telemetry.identify(packet.buffer, @interface.target_names)
162
159
  end
163
160
  else
164
161
  # Packet needs to be identified
165
- identified_packet = System.telemetry.identify!(packet.buffer,
166
- @interface.target_names)
162
+ identified_packet = System.telemetry.identify(packet.buffer, @interface.target_names)
167
163
  end
168
164
  end
169
165
 
170
- if identified_packet
166
+ unknown = false
167
+ unless identified_packet
168
+ unknown = true
169
+ identified_packet = System.telemetry.packet('UNKNOWN', 'UNKNOWN')
170
+ end
171
+
172
+ identified_packet.synchronize do
173
+ identified_packet.buffer = packet.buffer unless packet.stored
171
174
  identified_packet.received_time = packet.received_time
172
175
  identified_packet.stored = packet.stored
173
176
  identified_packet.extra = packet.extra
174
177
  packet = identified_packet
175
- else
176
- unknown_packet = System.telemetry.update!('UNKNOWN', 'UNKNOWN', packet.buffer)
177
- unknown_packet.received_time = packet.received_time
178
- unknown_packet.stored = packet.stored
179
- unknown_packet.extra = packet.extra
180
- packet = unknown_packet
181
- data_length = packet.length
182
- string = "#{@interface.name} - Unknown #{data_length} byte packet starting: "
183
- num_bytes_to_print = [UNKNOWN_BYTES_TO_PRINT, data_length].min
184
- data_to_print = packet.buffer(false)[0..(num_bytes_to_print - 1)]
185
- data_to_print.each_byte do |byte|
186
- string << sprintf("%02X", byte)
178
+
179
+ if unknown
180
+ data_length = packet.length
181
+ string = "#{@interface.name} - Unknown #{data_length} byte packet starting: "
182
+ num_bytes_to_print = [UNKNOWN_BYTES_TO_PRINT, data_length].min
183
+ data_to_print = packet.buffer(false)[0..(num_bytes_to_print - 1)]
184
+ data_to_print.each_byte do |byte|
185
+ string << sprintf("%02X", byte)
186
+ end
187
+ Logger.error string
187
188
  end
188
- Logger.error string
189
- end
190
189
 
191
- target = System.targets[packet.target_name]
192
- target.tlm_cnt += 1 if target
193
- packet.received_count += 1
194
- @identified_packet_callback.call(packet) if @identified_packet_callback
190
+ target = System.targets[packet.target_name]
191
+ target.tlm_cnt += 1 if target
192
+ packet.received_count += 1
193
+ @identified_packet_callback.call(packet) if @identified_packet_callback
195
194
 
195
+ # So we can release the mutex
196
+ packet = packet.clone
197
+ end
198
+
196
199
  # Write to routers
197
200
  @interface.routers.each do |router|
198
201
  begin
@@ -86,7 +86,7 @@ module Cosmos
86
86
  return if @sleeper.sleep(@initial_delay)
87
87
  loop do
88
88
  start = Time.now
89
- check_methods.each {|method| self.send(method.intern) }
89
+ check_methods.each {|method| self.public_send(method.intern) }
90
90
  now = Time.now
91
91
  @status = "#{now.formatted}: Checking groups took #{now - start}s"
92
92
  sleep_time = @task_delay - (now - start)
@@ -19,6 +19,11 @@ module Cosmos
19
19
  protected
20
20
 
21
21
  def handle_packet(packet)
22
+ unless System.allow_router_commanding
23
+ Logger.error "Router received command with router commanding disabled"
24
+ return
25
+ end
26
+
22
27
  # Start out assuming we will route to all associated interfaces
23
28
  interfaces = @interface.interfaces
24
29
 
@@ -653,7 +653,7 @@ module Cosmos
653
653
  end
654
654
  File.open(File.join(target_folder, 'procedures', "#{target.downcase}_noop.rb"), 'w') do |file|
655
655
  file.puts "require 'cosmos'"
656
- file.puts "require '#{File.basename(lib_filename)}'"
656
+ file.puts "load_utility '#{File.basename(lib_filename)}'"
657
657
  file.puts "\n"
658
658
  file.puts "#{target.downcase} = #{lib_filename.filename_to_class_name}.new"
659
659
  file.puts "#{target.downcase}.noop"
@@ -156,7 +156,7 @@ module Cosmos
156
156
  msg << "PDF Handbooks created successfully"
157
157
  progress_dialog.append_text(msg)
158
158
  else
159
- progress_dialog.append_text("\nPDF Handbooks could not be created.\n\nIs wkhtmltopdf in your PATH and are all existing pdfs closed?\n\nUsing version 0.11.0_rc1 of wkhtmltox is recommended which can be found at: http://download.gna.org/wkhtmltopdf/obsolete/\n\nVersion 0.12.x has shown issues with Handbook Creator's default templates.")
159
+ progress_dialog.append_text("\nPDF Handbooks could not be created.\n\nIs wkhtmltopdf in your PATH and are all existing pdfs closed?\n\nwkhtmltopdf can be found at: https://wkhtmltopdf.org/downloads.html.")
160
160
  end
161
161
  rescue => error
162
162
  progress_dialog.append_text("\n\nError processing:\n#{error.formatted}")
@@ -115,7 +115,7 @@ module Cosmos
115
115
  cover, cover_file = make_pdf_detail('cover', @pdf_cover_filename, @pdf_cover_title, target_name)
116
116
  header, header_file = make_pdf_detail('--header-spacing 3 --header-html', @pdf_header_filename, @pdf_header_title, target_name)
117
117
  footer, footer_file = make_pdf_detail('--footer-spacing 3 --footer-html', @pdf_footer_filename, @pdf_footer_title, target_name)
118
- system_call = "wkhtmltopdf -L #{@pdf_side_margin} -R #{@pdf_side_margin} -T #{@pdf_top_margin} -B #{@pdf_bottom_margin} -s Letter #{header} #{footer} #{cover} #{@pdf_toc} \"#{tmp_html_file.path}\" \"#{File.dirname(filename)}/#{File.basename(filename, '.*')}.pdf\""
118
+ system_call = "wkhtmltopdf --enable-local-file-access -L #{@pdf_side_margin} -R #{@pdf_side_margin} -T #{@pdf_top_margin} -B #{@pdf_bottom_margin} -s Letter #{header} #{footer} #{cover} #{@pdf_toc} \"#{tmp_html_file.path}\" \"#{File.dirname(filename)}/#{File.basename(filename, '.*')}.pdf\""
119
119
  status = nil
120
120
  begin
121
121
  Cosmos.set_working_dir(System.paths['HANDBOOKS']) do
@@ -973,8 +973,10 @@ module Cosmos
973
973
  if debug_text =~ /^@\S+$/ || @script_binding.local_variables.include?(debug_text.to_sym)
974
974
  debug_text = "puts #{debug_text}" # Automatically add puts to print it
975
975
  end
976
+ # Fortify: Dynamic Code Evaluation: Code Injection
976
977
  eval(debug_text, @script_binding, 'debug', 1)
977
978
  else
979
+ # Fortify: Dynamic Code Evaluation: Code Injection
978
980
  Object.class_eval(debug_text, 'debug', 1)
979
981
  end
980
982
  handle_output_io()
@@ -1489,7 +1491,7 @@ module Cosmos
1489
1491
  @@output_thread = nil
1490
1492
  end
1491
1493
 
1492
- @script.setReadOnly(false)
1494
+ @script.setReadOnly(false) unless @script.read_only
1493
1495
  @script.stop_highlight unless uncaught_exception
1494
1496
  select_tab_and_destroy_tabs_after_index(0)
1495
1497
  remove_tabs()
@@ -1722,7 +1724,8 @@ module Cosmos
1722
1724
  @active_script.setPlainText(data)
1723
1725
  end
1724
1726
  mark_breakpoints(filename)
1725
-
1727
+ @active_script.read_only = !File.writable?(filename)
1728
+ @active_script.setReadOnly(@active_script.read_only)
1726
1729
  @active_script.stop_highlight
1727
1730
  end
1728
1731
 
@@ -176,7 +176,7 @@ module Cosmos
176
176
  end
177
177
  end
178
178
 
179
- object.send(method_name)
179
+ object.public_send(method_name)
180
180
  result.result = :PASS
181
181
 
182
182
  if defined? ScriptRunnerFrame
@@ -865,13 +865,13 @@ module Cosmos
865
865
  suite = CustomTestSuite.new
866
866
  begin
867
867
  # Remove any previously defined suite setup methods
868
- CustomTestSuite.send(:remove_method, :setup)
868
+ CustomTestSuite.public_send(:remove_method, :setup)
869
869
  rescue NameError
870
870
  # NameError is raised if no setup method was defined
871
871
  end
872
872
  begin
873
873
  # Remove any previously defined suite teardown methods
874
- CustomTestSuite.send(:remove_method, :teardown)
874
+ CustomTestSuite.public_send(:remove_method, :teardown)
875
875
  rescue NameError
876
876
  # NameError is raised if no teardown method was defined
877
877
  end
@@ -884,7 +884,7 @@ module Cosmos
884
884
  inst = @@test_suites.detect {|my_suite| my_suite.class.to_s == suite_node.text}
885
885
  # Create a lambda which will call that one setup method
886
886
  body = lambda { inst.setup }
887
- CustomTestSuite.send(:define_method, :setup, &body)
887
+ CustomTestSuite.public_send(:define_method, :setup, &body)
888
888
  end
889
889
  if test_node.text == 'teardown'
890
890
  cur_suite.teardown = true
@@ -892,7 +892,7 @@ module Cosmos
892
892
  inst = @@test_suites.detect {|my_suite| my_suite.class.to_s == suite_node.text}
893
893
  # Create a lambda which will call that one teardown method
894
894
  body = lambda { inst.teardown}
895
- CustomTestSuite.send(:define_method, :teardown, &body)
895
+ CustomTestSuite.public_send(:define_method, :teardown, &body)
896
896
  end
897
897
  end
898
898
 
@@ -455,7 +455,7 @@ module Cosmos
455
455
  def self.post_options_parsed_hook(options)
456
456
  if options.input_files or options.dart
457
457
  normalize_config_options(options)
458
-
458
+
459
459
  # Process config file
460
460
  raise "Configuration File must be specified for command line processing" unless options.config_file
461
461
 
@@ -675,7 +675,7 @@ module Cosmos
675
675
  process_args = [batch_name, @input_filenames, @log_dir, output_extension, @batch_filenames, @packet_log_frame.time_start, @packet_log_frame.time_end]
676
676
  end
677
677
 
678
- @tlm_extractor_processor.send(process_method, *process_args) do |input_file_index, packet_count, file_progress|
678
+ @tlm_extractor_processor.public_send(process_method, *process_args) do |input_file_index, packet_count, file_progress|
679
679
  # Handle Cancel
680
680
  break if @cancel
681
681
 
@@ -760,7 +760,7 @@ module Cosmos
760
760
  process_args = [batch_name, @log_dir, output_extension, @batch_filenames, @packet_log_frame.time_start, @packet_log_frame.time_end, @dart_meta_frame.meta_filters]
761
761
  end
762
762
 
763
- @tlm_extractor_processor.send(process_method, *process_args) do |percentage, message|
763
+ @tlm_extractor_processor.public_send(process_method, *process_args) do |percentage, message|
764
764
  # Handle Cancel
765
765
  break if @cancel
766
766
  progress_dialog.append_text(message)
@@ -385,10 +385,7 @@ module Cosmos
385
385
 
386
386
  # Print column headings to output file
387
387
  @output_file.print "%" if @matlab_header
388
- column_names().each do |column_name|
389
- @output_file.print column_name
390
- @output_file.print @delimiter
391
- end
388
+ @output_file.print column_names.join(@delimiter)
392
389
  @output_file.puts ""
393
390
  @row_index += 1
394
391
  end
@@ -72,13 +72,13 @@ module Cosmos
72
72
  items = []
73
73
  configs.each { |config| config.mode = :dart; items.concat(config.normal_items); config.open_output_file }
74
74
  items.uniq!
75
-
75
+
76
76
  time_start = Time.utc(1970, 1, 1) unless time_start
77
77
  time_end = Time.now unless time_end
78
78
 
79
79
  results = {}
80
80
  begin
81
- server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'])
81
+ server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'], 1.0, Cosmos::System.x_csrf_token)
82
82
 
83
83
  index = 0
84
84
  items.each do |item_type, target_name, packet_name, item_name, value_type, dart_reduction, dart_reduced_type|
@@ -116,7 +116,7 @@ module Cosmos
116
116
  rescue Exception => error
117
117
  yield(index.to_f / items.length, "Error querying #{query_string} : #{error.class}:#{error.message}\n#{error.backtrace.join("\n")}\n") if block_given?
118
118
  return # Bail out because something bad happened
119
- end
119
+ end
120
120
  end
121
121
 
122
122
  configs.each { |config| config.process_dart(results) }
@@ -45,7 +45,7 @@ module Cosmos
45
45
 
46
46
  # Execute each query
47
47
  results = {}
48
- server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'])
48
+ server = JsonDRbObject.new(System.connect_hosts['DART_DECOM'], System.ports['DART_DECOM'], 1.0, Cosmos::System.x_csrf_token)
49
49
  time_start = Time.utc(1970, 1, 1) unless time_start
50
50
  time_end = Time.now unless time_end
51
51
  progress_dialog.set_step_progress(0) if progress_dialog
@@ -146,7 +146,7 @@ module Cosmos
146
146
  'clear_all']
147
147
  @json_drb.method_whitelist = whitelist
148
148
  begin
149
- @json_drb.start_service System.listen_hosts['TLMVIEWER_API'], port, self
149
+ @json_drb.start_service System.listen_hosts['TLMVIEWER_API'], port, self, 1000, System
150
150
  rescue Exception
151
151
  raise FatalError.new("Error starting JsonDRb on port #{port}.\nPerhaps a Telemetry Viewer is already running?")
152
152
  end
@@ -171,7 +171,7 @@ module Cosmos
171
171
 
172
172
  ConfigParser.splash = nil
173
173
  end
174
-
174
+
175
175
  hide() unless options.show_main
176
176
  end
177
177
 
@@ -61,6 +61,8 @@ module Cosmos
61
61
  end
62
62
 
63
63
  def eval_str(string_to_eval)
64
+ # Fortify: Dynamic Code Evaluation: Code Injection
65
+ # TODO: Not sure how to sanitize this string
64
66
  @screen.instance_eval(string_to_eval)
65
67
  end
66
68
 
@@ -397,7 +397,7 @@ module Cosmos
397
397
  # @param hashing_algorithm [String] Hashing algorithm to use
398
398
  # @return [Digest::<algorithm>] The hashing sum object
399
399
  def self.hash_files(filenames, additional_data = nil, hashing_algorithm = 'MD5')
400
- digest = Digest.const_get(hashing_algorithm).send('new')
400
+ digest = Digest.const_get(hashing_algorithm).public_send('new')
401
401
 
402
402
  Cosmos.set_working_dir do
403
403
  filenames.each do |filename|
@@ -37,7 +37,7 @@ module Cosmos
37
37
  @tlm_packets.each do |name, packet|
38
38
  ids = packet.id_items
39
39
  ids.each do |id|
40
- packet.send((id.name + '=').to_sym, id.id_value)
40
+ packet.public_send((id.name + '=').to_sym, id.id_value)
41
41
  end
42
42
  end
43
43