cosmos 4.4.1 → 4.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build_v4.yml +33 -0
- data/Dockerfile +10 -4
- data/Gemfile +1 -1
- data/Manifest.txt +26 -2
- data/README.md +4 -1
- data/Rakefile +33 -27
- data/autohotkey/tools/cmd_extractor.ahk +11 -9
- data/autohotkey/tools/cmd_sender.ahk +1 -1
- data/autohotkey/tools/cmd_sequence.ahk +1 -1
- data/autohotkey/tools/data_viewer.ahk +1 -1
- data/autohotkey/tools/limits_monitor.ahk +1 -1
- data/autohotkey/tools/packet_viewer.ahk +1 -1
- data/autohotkey/tools/script_runner.ahk +1 -1
- data/autohotkey/tools/test_runner2.ahk +1 -1
- data/autohotkey/tools/tlm_grapher.ahk +1 -1
- data/autohotkey/tools/tlm_grapher3.ahk +1 -1
- data/autohotkey/tools/tlm_viewer.ahk +1 -1
- data/autohotkey/tools/tlm_viewer2.ahk +1 -1
- data/autohotkey/tools/tlm_viewer5.ahk +1 -1
- data/bin/rubysloc +73 -28
- data/bin/xtce_converter +1 -1
- data/cosmos.gemspec +6 -12
- data/data/config/interface_modifiers.yaml +3 -2
- data/data/config/system.yaml +81 -24
- data/data/crc.txt +435 -435
- data/demo/Rakefile +4 -4
- data/demo/config/data/crc.txt +250 -250
- data/demo/config/system/system.txt +15 -7
- data/demo/config/system/system2.txt +15 -7
- data/demo/config/system/system_alt_ports.txt +15 -7
- data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -1
- data/demo/config/tools/handbook_creator/default_toc.xsl +59 -59
- data/ext/cosmos/ext/buffered_file/buffered_file.c +2 -2
- data/ext/cosmos/ext/config_parser/config_parser.c +1 -2
- data/ext/cosmos/ext/line_graph/line_graph.c +53 -94
- data/ext/cosmos/ext/packet/packet.c +0 -6
- data/ext/cosmos/ext/platform/platform.c +56 -21
- data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +4 -8
- data/ext/cosmos/ext/structure/structure.c +12 -0
- data/extensions/vscode/.gitignore +4 -0
- data/extensions/vscode/.vscode/launch.json +32 -0
- data/extensions/vscode/.vscode/settings.json +13 -0
- data/extensions/vscode/.vscode/tasks.json +79 -0
- data/extensions/vscode/License.txt +879 -0
- data/extensions/vscode/README.md +9 -0
- data/extensions/vscode/client/License.txt +879 -0
- data/extensions/vscode/client/README.md +39 -0
- data/extensions/vscode/client/cosmos.configuration.json +23 -0
- data/extensions/vscode/client/images/icon.png +0 -0
- data/extensions/vscode/client/package-lock.json +414 -0
- data/extensions/vscode/client/package.json +105 -0
- data/extensions/vscode/client/src/extension.ts +132 -0
- data/extensions/vscode/client/src/screen_preview.rb +25 -0
- data/extensions/vscode/client/syntaxes/cosmos.tmLanguage.json +219 -0
- data/extensions/vscode/client/tsconfig.json +17 -0
- data/extensions/vscode/package-lock.json +26 -0
- data/extensions/vscode/package.json +35 -0
- data/extensions/vscode/server/License.txt +879 -0
- data/extensions/vscode/server/package-lock.json +236 -0
- data/extensions/vscode/server/package.json +29 -0
- data/extensions/vscode/server/src/server.ts +59 -0
- data/extensions/vscode/server/tsconfig.json +16 -0
- data/install/Rakefile +4 -4
- data/install/config/data/crc.txt +145 -145
- data/install/config/system/system.txt +15 -7
- data/install/config/tools/handbook_creator/default_toc.xsl +59 -59
- data/lib/cosmos/config/config_parser.rb +2 -10
- data/lib/cosmos/core_ext/class.rb +10 -0
- data/lib/cosmos/core_ext/time.rb +5 -3
- data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
- data/lib/cosmos/dart/lib/dart_common.rb +3 -3
- data/lib/cosmos/dart/lib/dart_decommutator.rb +4 -4
- data/lib/cosmos/dart/processes/dart_decom_server.rb +1 -1
- data/lib/cosmos/dart/processes/dart_master.rb +1 -1
- data/lib/cosmos/dart/spec/dart/dart_database_cleaner_spec.rb +2 -2
- data/lib/cosmos/gui/qt.rb +10 -10
- data/lib/cosmos/gui/qt_tool.rb +17 -12
- data/lib/cosmos/gui/text/completion_text_edit.rb +2 -0
- data/lib/cosmos/gui/widgets/dart_meta_frame.rb +1 -1
- data/lib/cosmos/interfaces/dart_status_interface.rb +1 -1
- data/lib/cosmos/interfaces/linc_interface.rb +3 -3
- data/lib/cosmos/interfaces/protocols/burst_protocol.rb +1 -1
- data/lib/cosmos/interfaces/protocols/crc_protocol.rb +1 -1
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -3
- data/lib/cosmos/interfaces/serial_interface.rb +7 -1
- data/lib/cosmos/interfaces/stream_interface.rb +1 -1
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +16 -16
- data/lib/cosmos/io/io_multiplexer.rb +6 -2
- data/lib/cosmos/io/json_drb.rb +3 -11
- data/lib/cosmos/io/json_drb_object.rb +7 -2
- data/lib/cosmos/io/json_drb_rack.rb +25 -5
- data/lib/cosmos/io/json_rpc.rb +1 -1
- data/lib/cosmos/io/posix_serial_driver.rb +60 -22
- data/lib/cosmos/io/serial_driver.rb +11 -8
- data/lib/cosmos/io/win32_serial_driver.rb +8 -1
- data/lib/cosmos/packets/packet.rb +8 -8
- data/lib/cosmos/packets/packet_config.rb +1 -1
- data/lib/cosmos/packets/packet_item_limits.rb +2 -14
- data/lib/cosmos/packets/parsers/xtce_converter.rb +10 -10
- data/lib/cosmos/packets/parsers/xtce_parser.rb +3 -0
- data/lib/cosmos/packets/structure.rb +18 -5
- data/lib/cosmos/packets/structure_item.rb +4 -21
- data/lib/cosmos/script/api_shared.rb +18 -1
- data/lib/cosmos/script/extract.rb +1 -1
- data/lib/cosmos/script/script.rb +4 -11
- data/lib/cosmos/streams/serial_stream.rb +11 -6
- data/lib/cosmos/system/system.rb +47 -13
- data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +15 -0
- data/lib/cosmos/tools/cmd_sender/cmd_params.rb +25 -3
- data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +7 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +0 -5
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +10 -8
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +2 -2
- data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +1 -1
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +29 -26
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +1 -1
- data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +5 -0
- data/lib/cosmos/tools/config_editor/config_editor.rb +1 -1
- data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +1 -1
- data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +1 -1
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +5 -2
- data/lib/cosmos/tools/test_runner/test.rb +1 -1
- data/lib/cosmos/tools/test_runner/test_runner.rb +4 -4
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +3 -3
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -4
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +3 -3
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +2 -2
- data/lib/cosmos/tools/tlm_viewer/widgets/canvasdot_widget.rb +2 -0
- data/lib/cosmos/top_level.rb +1 -1
- data/lib/cosmos/utilities/simulated_target.rb +1 -1
- data/lib/cosmos/version.rb +5 -5
- data/make_gems.sh +1 -1
- data/spec/core_ext/class_spec.rb +54 -0
- data/spec/core_ext/time_spec.rb +4 -0
- data/spec/gui/qt_spec.rb +1 -1
- data/spec/gui/utilities/script_module_gui_spec.rb +1 -1
- data/spec/interfaces/linc_interface_spec.rb +1 -1
- data/spec/interfaces/serial_interface_spec.rb +1 -5
- data/spec/io/json_drb_rack_spec.rb +166 -0
- data/spec/io/json_rpc_spec.rb +4 -5
- data/spec/io/posix_serial_driver_spec.rb +87 -0
- data/spec/io/win32_serial_driver_spec.rb +17 -1
- data/spec/packet_logs/packet_log_reader_spec.rb +34 -35
- data/spec/packets/packet_item_limits_spec.rb +6 -33
- data/spec/packets/structure_item_spec.rb +3 -21
- data/spec/script/extract_spec.rb +4 -1
- data/spec/system/system_spec.rb +109 -1
- data/spec/tools/cmd_tlm_server/api_spec.rb +12 -12
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +2 -2
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +4 -3
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
- data/spec/top_level/top_level_spec.rb +2 -2
- data/spec/utilities/logger_spec.rb +3 -3
- data/test/performance/Rakefile +4 -4
- data/test/performance/config/data/crc.txt +67 -48
- metadata +59 -9
- data/.coveralls.yml +0 -1
- data/.travis.yml +0 -16
data/lib/cosmos/system/system.rb
CHANGED
@@ -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
|
-
|
600
|
-
@listen_hosts['
|
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
|
-
|
604
|
-
@listen_hosts['
|
605
|
-
@listen_hosts['
|
606
|
-
@listen_hosts['
|
607
|
-
@listen_hosts['
|
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 =
|
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
|
-
|
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 = "'#{
|
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.
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
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.
|
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.
|
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
|
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
|
166
|
-
@interface.target_names)
|
162
|
+
identified_packet = System.telemetry.identify(packet.buffer, @interface.target_names)
|
167
163
|
end
|
168
164
|
end
|
169
165
|
|
170
|
-
|
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
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
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.
|
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 "
|
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\
|
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
|
|
@@ -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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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()
|
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
|
|
data/lib/cosmos/top_level.rb
CHANGED
@@ -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).
|
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|
|