cosmos 4.4.2 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +6 -2
- data/Manifest.txt +25 -0
- data/README.md +4 -0
- data/Rakefile +3 -8
- data/bin/rubysloc +73 -28
- data/cosmos.gemspec +1 -1
- data/data/config/interface_modifiers.yaml +3 -2
- data/data/config/system.yaml +81 -24
- data/data/crc.txt +426 -426
- data/demo/config/data/crc.txt +233 -233
- 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/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/config/data/crc.txt +132 -132
- data/install/config/system/system.txt +15 -7
- data/lib/cosmos/core_ext/time.rb +3 -1
- data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
- 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/gui/qt_tool.rb +10 -12
- 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/serial_interface.rb +7 -1
- data/lib/cosmos/io/json_drb.rb +2 -2
- 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/structure.rb +11 -2
- data/lib/cosmos/script/api_shared.rb +8 -1
- data/lib/cosmos/script/script.rb +2 -9
- data/lib/cosmos/streams/serial_stream.rb +11 -6
- data/lib/cosmos/system/system.rb +43 -12
- 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/cmd_tlm_server.rb +2 -2
- 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_config.rb +1 -1
- 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/version.rb +5 -5
- data/spec/core_ext/time_spec.rb +4 -0
- 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 +81 -0
- data/spec/io/win32_serial_driver_spec.rb +17 -1
- data/spec/system/system_spec.rb +108 -0
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
- metadata +31 -6
@@ -24,7 +24,8 @@ module Cosmos
|
|
24
24
|
read_polling_period = 0.01,
|
25
25
|
read_max_length = 1000,
|
26
26
|
flow_control = :NONE,
|
27
|
-
data_bits = 8
|
27
|
+
data_bits = 8,
|
28
|
+
struct = [])
|
28
29
|
|
29
30
|
# Verify Parameters
|
30
31
|
port_name = '\\\\.\\' + port_name if port_name =~ /^COM[0-9]{2,3}$/
|
@@ -78,6 +79,12 @@ module Cosmos
|
|
78
79
|
# 0x03 - RTS_CONTROL_TOGGLE - Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low.
|
79
80
|
dcb.write('fRtsControl', 0x03)
|
80
81
|
end
|
82
|
+
# Allow the end user to write arbitrary values into the Windows DCB structure
|
83
|
+
unless struct.empty?
|
84
|
+
struct.each do |key, value|
|
85
|
+
dcb.write(key, value.to_i)
|
86
|
+
end
|
87
|
+
end
|
81
88
|
Win32.set_comm_state(@handle, dcb)
|
82
89
|
|
83
90
|
# Configure Timeouts, the WinAPI structure is COMMTIMEOUTS:
|
@@ -464,9 +464,18 @@ module Cosmos
|
|
464
464
|
|
465
465
|
protected
|
466
466
|
|
467
|
+
MUTEX = Mutex.new
|
468
|
+
|
469
|
+
def setup_mutex
|
470
|
+
return if @mutex
|
471
|
+
MUTEX.synchronize do
|
472
|
+
@mutex ||= Mutex.new
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
467
476
|
# Take the structure mutex to ensure the buffer does not change while you perform activities
|
468
477
|
def synchronize
|
469
|
-
|
478
|
+
setup_mutex()
|
470
479
|
@mutex.synchronize {|| yield}
|
471
480
|
end
|
472
481
|
|
@@ -476,7 +485,7 @@ module Cosmos
|
|
476
485
|
# lower level calls to go forward without getting the mutex
|
477
486
|
def synchronize_allow_reads(top = false)
|
478
487
|
@mutex_allow_reads ||= false
|
479
|
-
|
488
|
+
setup_mutex()
|
480
489
|
if top
|
481
490
|
@mutex.synchronize do
|
482
491
|
@mutex_allow_reads = Thread.current
|
@@ -9,6 +9,13 @@
|
|
9
9
|
# attribution addendums as found in the LICENSE.txt
|
10
10
|
|
11
11
|
module Cosmos
|
12
|
+
# Error raised by the API when a check fails
|
13
|
+
class CheckError < RuntimeError; end
|
14
|
+
# Error raised when a Script should be stopped
|
15
|
+
class StopScript < StandardError; end
|
16
|
+
# Error raised when a TestCase should be skipped by TestRunner
|
17
|
+
class SkipTestCase < StandardError; end
|
18
|
+
|
12
19
|
module ApiShared
|
13
20
|
DEFAULT_TLM_POLLING_RATE = 0.25
|
14
21
|
|
@@ -942,7 +949,7 @@ module Cosmos
|
|
942
949
|
end
|
943
950
|
|
944
951
|
def run_tlm_viewer(action, display_name = '')
|
945
|
-
tlm_viewer = JsonDRbObject.new System.connect_hosts['TLMVIEWER_API'], System.ports['TLMVIEWER_API']
|
952
|
+
tlm_viewer = JsonDRbObject.new System.connect_hosts['TLMVIEWER_API'], System.ports['TLMVIEWER_API'], 1.0, Cosmos::System.x_csrf_token
|
946
953
|
begin
|
947
954
|
yield tlm_viewer
|
948
955
|
tlm_viewer.disconnect
|
data/lib/cosmos/script/script.rb
CHANGED
@@ -25,13 +25,6 @@ $disconnect_all_targets = false
|
|
25
25
|
$cmd_tlm_replay_mode = false
|
26
26
|
|
27
27
|
module Cosmos
|
28
|
-
# Error raised by the API when a check fails
|
29
|
-
class CheckError < RuntimeError; end
|
30
|
-
# Error raised when a Script should be stopped
|
31
|
-
class StopScript < StandardError; end
|
32
|
-
# Error raised when a TestCase should be skipped by TestRunner
|
33
|
-
class SkipTestCase < StandardError; end
|
34
|
-
|
35
28
|
# Provides a proxy to both a disconnected CmdTlmServer instance and the real
|
36
29
|
# JsonDRbObject which communicates with the real CmdTlmServer. If targets
|
37
30
|
# are disconnected their method calls are forwarded to the disconnected
|
@@ -49,9 +42,9 @@ module Cosmos
|
|
49
42
|
end
|
50
43
|
# Start a Json connect to the real server
|
51
44
|
if $cmd_tlm_replay_mode
|
52
|
-
@cmd_tlm_server = JsonDRbObject.new(System.connect_hosts['REPLAY_API'], System.ports['REPLAY_API'])
|
45
|
+
@cmd_tlm_server = JsonDRbObject.new(System.connect_hosts['REPLAY_API'], System.ports['REPLAY_API'], 1.0, Cosmos::System.x_csrf_token)
|
53
46
|
else
|
54
|
-
@cmd_tlm_server = JsonDRbObject.new(System.connect_hosts['CTS_API'], System.ports['CTS_API'])
|
47
|
+
@cmd_tlm_server = JsonDRbObject.new(System.connect_hosts['CTS_API'], System.ports['CTS_API'], 1.0, Cosmos::System.x_csrf_token)
|
55
48
|
end
|
56
49
|
end
|
57
50
|
|
@@ -35,8 +35,10 @@ module Cosmos
|
|
35
35
|
# complete. Pass nil to create no timeout. The {SerialDriver} will
|
36
36
|
# continously try to read data until it has received data or an error
|
37
37
|
# occurs.
|
38
|
-
# @param flow_control [Symbol] Currently supported :NONE
|
38
|
+
# @param flow_control [Symbol] Currently supported :NONE, :RTSCTS (default :NONE)
|
39
39
|
# @param data_bits [Integer] Number of data bits (default 8)
|
40
|
+
# @param struct [Array] Array of arrays of fields and values to set in the
|
41
|
+
# Windows DCB or POSIX structure
|
40
42
|
def initialize(write_port_name,
|
41
43
|
read_port_name,
|
42
44
|
baud_rate,
|
@@ -45,7 +47,8 @@ module Cosmos
|
|
45
47
|
write_timeout,
|
46
48
|
read_timeout,
|
47
49
|
flow_control = :NONE,
|
48
|
-
data_bits = 8
|
50
|
+
data_bits = 8,
|
51
|
+
struct = [])
|
49
52
|
super()
|
50
53
|
|
51
54
|
# The SerialDriver class will validate the parameters
|
@@ -69,7 +72,8 @@ module Cosmos
|
|
69
72
|
@write_timeout,
|
70
73
|
@read_timeout,
|
71
74
|
@flow_control,
|
72
|
-
@data_bits
|
75
|
+
@data_bits,
|
76
|
+
struct)
|
73
77
|
else
|
74
78
|
@write_serial_port = nil
|
75
79
|
end
|
@@ -84,7 +88,8 @@ module Cosmos
|
|
84
88
|
@write_timeout,
|
85
89
|
@read_timeout,
|
86
90
|
@flow_control,
|
87
|
-
@data_bits
|
91
|
+
@data_bits,
|
92
|
+
struct)
|
88
93
|
end
|
89
94
|
else
|
90
95
|
@read_serial_port = nil
|
@@ -151,5 +156,5 @@ module Cosmos
|
|
151
156
|
@connected = false
|
152
157
|
end
|
153
158
|
end
|
154
|
-
end
|
155
|
-
end
|
159
|
+
end
|
160
|
+
end
|
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
|
@@ -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
|
|
@@ -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
|
@@ -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"
|
@@ -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
|
@@ -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
|