cosmos 3.5.3 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Manifest.txt +3 -0
- data/autohotkey/procedures/script_test.rb +4 -0
- data/autohotkey/tools/script_runner2.ahk +13 -0
- data/cosmos.gemspec +2 -2
- data/data/crc.txt +17 -17
- data/demo/config/data/crc.txt +10 -7
- data/demo/config/targets/INST/cmd_tlm/_ccsds_cmd.txt +9 -0
- data/demo/config/targets/INST/cmd_tlm/_ccsds_tlm.txt +19 -0
- data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +19 -84
- data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +27 -110
- data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +3 -220
- data/demo/config/tools/tlm_extractor/_adcs_time.txt +2 -0
- data/demo/config/tools/tlm_extractor/tlm_extractor.txt +1 -1
- data/demo/config/tools/tlm_extractor/tlm_extractor2.txt +1 -1
- data/demo/config/tools/tlm_extractor/tlm_extractor3.txt +1 -1
- data/demo/config/tools/tlm_extractor/tlm_extractor4.txt +1 -1
- data/lib/cosmos/config/config_parser.rb +54 -1
- data/lib/cosmos/gui/utilities/script_module_gui.rb +31 -20
- data/lib/cosmos/io/json_drb.rb +33 -23
- data/lib/cosmos/io/json_drb_object.rb +4 -1
- data/lib/cosmos/io/tcpip_server.rb +1 -1
- data/lib/cosmos/packets/packet_config.rb +5 -1
- data/lib/cosmos/packets/parsers/macro_parser.rb +1 -1
- data/lib/cosmos/script/scripting.rb +28 -0
- data/lib/cosmos/streams/tcpip_socket_stream.rb +72 -19
- data/lib/cosmos/system/target.rb +16 -2
- data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +28 -17
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +14 -2
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +1 -1
- data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +27 -20
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +2 -2
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +40 -36
- data/lib/cosmos/version.rb +5 -5
- data/spec/config/config_parser_spec.rb +1 -1
- data/spec/io/json_drb_spec.rb +7 -21
- data/spec/packets/packet_config_spec.rb +12 -12
- data/spec/packets/parsers/format_string_parser_spec.rb +3 -3
- data/spec/packets/parsers/limits_parser_spec.rb +10 -10
- data/spec/packets/parsers/limits_response_parser_spec.rb +2 -2
- data/spec/packets/parsers/macro_parser_spec.rb +6 -6
- data/spec/packets/parsers/packet_parser_spec.rb +1 -1
- data/spec/packets/parsers/processor_parser_spec.rb +2 -2
- data/spec/packets/parsers/state_parser_spec.rb +1 -1
- data/spec/script/scripting_spec.rb +23 -0
- data/spec/streams/tcpip_socket_stream_spec.rb +28 -0
- data/spec/system/system_spec.rb +20 -20
- data/spec/system/target_spec.rb +10 -10
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +30 -22
- metadata +9 -6
@@ -48,6 +48,7 @@ module Cosmos
|
|
48
48
|
@port = port
|
49
49
|
@mutex = Mutex.new
|
50
50
|
@socket = nil
|
51
|
+
@pipe_reader, @pipe_writer = IO.pipe
|
51
52
|
@id = 0
|
52
53
|
@request_in_progress = false
|
53
54
|
@connect_timeout = connect_timeout
|
@@ -58,6 +59,7 @@ module Cosmos
|
|
58
59
|
# Disconnects from the JSON server
|
59
60
|
def disconnect
|
60
61
|
Cosmos.close_socket(@socket)
|
62
|
+
@pipe_writer.write('.')
|
61
63
|
# Cannot set @socket to nil here because this method can be called by
|
62
64
|
# other threads and @socket being nil would cause unexpected errors in method_missing
|
63
65
|
# Also don't want to take the mutex so that we can interrupt method_missing if necessary
|
@@ -113,6 +115,7 @@ module Cosmos
|
|
113
115
|
addr = Socket.pack_sockaddr_in(@port, @hostname)
|
114
116
|
@socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
115
117
|
@socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
118
|
+
@pipe_reader, @pipe_writer = IO.pipe
|
116
119
|
begin
|
117
120
|
@socket.connect_nonblock(addr)
|
118
121
|
rescue IO::WaitWritable
|
@@ -159,7 +162,7 @@ module Cosmos
|
|
159
162
|
STDOUT.puts request_data if JsonDRb.debug?
|
160
163
|
@request_in_progress = true
|
161
164
|
JsonDRb.send_data(@socket, request_data)
|
162
|
-
response_data = JsonDRb.receive_message(@socket, '')
|
165
|
+
response_data = JsonDRb.receive_message(@socket, '', @pipe_reader)
|
163
166
|
@request_in_progress = false
|
164
167
|
STDOUT.puts "\nResponse:\n" if JsonDRb.debug?
|
165
168
|
STDOUT.puts response_data if JsonDRb.debug?
|
@@ -483,7 +483,7 @@ module Cosmos
|
|
483
483
|
stream_protocol.disconnect
|
484
484
|
stream_protocol.stream.raw_logger_pair.stop if stream_protocol.stream.raw_logger_pair
|
485
485
|
indexes_to_delete.unshift(index) # Put later indexes at front of array
|
486
|
-
rescue Errno::ECONNRESET, Errno::ECONNABORTED
|
486
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError
|
487
487
|
# Client has disconnected
|
488
488
|
Logger.instance.info "Tcpip server lost write connection to #{hostname}(#{host_ip}):#{port}"
|
489
489
|
stream_protocol.disconnect
|
@@ -95,13 +95,16 @@ module Cosmos
|
|
95
95
|
# @param filename [String] The name of the configuration file
|
96
96
|
# @param target_name [String] The target name
|
97
97
|
def process_file(filename, process_target_name)
|
98
|
+
# Partial files are included into another file and thus aren't directly processed
|
99
|
+
return if File.basename(filename)[0] == '_' # Partials start with underscore
|
100
|
+
|
98
101
|
@converted_type = nil
|
99
102
|
@converted_bit_size = nil
|
100
103
|
@proc_text = ''
|
101
104
|
@building_generic_conversion = false
|
102
105
|
|
103
106
|
process_target_name = process_target_name.upcase
|
104
|
-
parser = ConfigParser.new("
|
107
|
+
parser = ConfigParser.new("http://cosmosrb.com/docs/cmdtlm")
|
105
108
|
parser.parse_file(filename) do |keyword, params|
|
106
109
|
|
107
110
|
if @building_generic_conversion
|
@@ -230,6 +233,7 @@ module Cosmos
|
|
230
233
|
# This simulates an array of structures of multiple items in the packet by repeating
|
231
234
|
# each item in the list multiple times with a different "index" added to the name.
|
232
235
|
when 'MACRO_APPEND_START'
|
236
|
+
Logger.warn "MACRO_APPEND_START/END is deprecated. Please use new ERB macro syntax."
|
233
237
|
MacroParser.start(parser)
|
234
238
|
|
235
239
|
# End the creation of a macro-expanded list of items
|
@@ -54,7 +54,7 @@ module Cosmos
|
|
54
54
|
if first_index < last_index
|
55
55
|
@macro.indices = (first_index..last_index).to_a
|
56
56
|
else
|
57
|
-
@macro.indices = (last_index..first_index).to_a
|
57
|
+
@macro.indices = (last_index..first_index).to_a.reverse
|
58
58
|
end
|
59
59
|
@macro.format = parser.parameters[2] ? parser.parameters[2] : '%s%d'
|
60
60
|
@macro.format_order = get_format_order()
|
@@ -69,6 +69,34 @@ module Cosmos
|
|
69
69
|
prompt_combo_box(string, options)
|
70
70
|
end
|
71
71
|
|
72
|
+
def _file_dialog(message, directory, select_files = true)
|
73
|
+
answer = ''
|
74
|
+
files = Dir["#{directory}/*"]
|
75
|
+
if select_files
|
76
|
+
files.select! {|f| !File.directory? f }
|
77
|
+
else
|
78
|
+
files.select! {|f| File.directory? f }
|
79
|
+
end
|
80
|
+
while answer.empty?
|
81
|
+
print message + "\n" + files.join("\n") + "\n<Type file name>:"
|
82
|
+
answer = gets
|
83
|
+
answer.chomp!
|
84
|
+
end
|
85
|
+
return answer
|
86
|
+
end
|
87
|
+
def save_file_dialog(directory = Cosmos::USERPATH, message = "Save File")
|
88
|
+
_file_dialog(message, directory)
|
89
|
+
end
|
90
|
+
def open_file_dialog(directory = Cosmos::USERPATH, message = "Open File")
|
91
|
+
_file_dialog(message, directory)
|
92
|
+
end
|
93
|
+
def open_files_dialog(directory = Cosmos::USERPATH, message = "Open File(s)")
|
94
|
+
_file_dialog(message, directory)
|
95
|
+
end
|
96
|
+
def open_directory_dialog(directory = Cosmos::USERPATH, message = "Open Directory")
|
97
|
+
_file_dialog(message, directory, false)
|
98
|
+
end
|
99
|
+
|
72
100
|
# Creates a string with the parameters upcased
|
73
101
|
def _upcase(target_name, packet_name, item_name)
|
74
102
|
"#{target_name.upcase} #{packet_name.upcase} #{item_name.upcase}"
|
@@ -20,6 +20,8 @@ module Cosmos
|
|
20
20
|
class TcpipSocketStream < Stream
|
21
21
|
attr_reader :write_socket
|
22
22
|
|
23
|
+
FAST_READ = (RUBY_VERSION > "2.1")
|
24
|
+
|
23
25
|
# @param write_socket [Socket] Socket to write
|
24
26
|
# @param read_socket [Socket] Socket to read
|
25
27
|
# @param write_timeout [Float|nil] Number of seconds to wait for the write
|
@@ -39,6 +41,7 @@ module Cosmos
|
|
39
41
|
# Mutex on write is needed to protect from commands coming in from more
|
40
42
|
# than one tool
|
41
43
|
@write_mutex = Mutex.new
|
44
|
+
@pipe_reader, @pipe_writer = IO.pipe
|
42
45
|
@connected = false
|
43
46
|
end
|
44
47
|
|
@@ -48,27 +51,66 @@ module Cosmos
|
|
48
51
|
|
49
52
|
# No read mutex is needed because there is only one stream procesor
|
50
53
|
# reading
|
51
|
-
|
52
|
-
data = @read_socket.recv_nonblock(65535)
|
53
|
-
@raw_logger_pair.read_logger.write(data) if @raw_logger_pair
|
54
|
-
rescue IO::WaitReadable
|
55
|
-
# Wait for the socket to be ready for reading or for the timeout
|
54
|
+
if FAST_READ
|
56
55
|
begin
|
57
|
-
|
56
|
+
while true # Loop until we get some data
|
57
|
+
data = @read_socket.read_nonblock(65535, exception: false)
|
58
|
+
raise EOFError, 'end of file reached' unless data
|
59
|
+
if data == :wait_readable
|
60
|
+
# Wait for the socket to be ready for reading or for the timeout
|
61
|
+
begin
|
62
|
+
result = IO.fast_select([@read_socket, @pipe_reader], nil, nil, @read_timeout)
|
63
|
+
# If select returns something it means the socket is now available for
|
64
|
+
# reading so retry the read. If it returns nil it means we timed out.
|
65
|
+
# If the pipe is present that means we closed the socket
|
66
|
+
if result
|
67
|
+
if result.include?(@pipe_reader)
|
68
|
+
raise IOError
|
69
|
+
else
|
70
|
+
next
|
71
|
+
end
|
72
|
+
else
|
73
|
+
raise Timeout::Error, "Read Timeout"
|
74
|
+
end
|
75
|
+
rescue IOError, Errno::ENOTSOCK
|
76
|
+
# These can happen with the socket being closed while waiting on select
|
77
|
+
data = ''
|
78
|
+
end
|
79
|
+
end
|
80
|
+
@raw_logger_pair.read_logger.write(data) if @raw_logger_pair
|
81
|
+
break
|
82
|
+
end
|
83
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError, Errno::ENOTSOCK
|
84
|
+
data = ''
|
85
|
+
end
|
86
|
+
else
|
87
|
+
begin
|
88
|
+
data = @read_socket.read_nonblock(65535)
|
89
|
+
@raw_logger_pair.read_logger.write(data) if @raw_logger_pair
|
90
|
+
rescue IO::WaitReadable
|
91
|
+
# Wait for the socket to be ready for reading or for the timeout
|
92
|
+
begin
|
93
|
+
result = IO.fast_select([@read_socket, @pipe_reader], nil, nil, @read_timeout)
|
58
94
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
95
|
+
# If select returns something it means the socket is now available for
|
96
|
+
# reading so retry the read. If it returns nil it means we timed out.
|
97
|
+
# If the pipe is present that means we closed the socket
|
98
|
+
if result
|
99
|
+
if result.include?(@pipe_reader)
|
100
|
+
raise IOError
|
101
|
+
else
|
102
|
+
retry
|
103
|
+
end
|
104
|
+
else
|
105
|
+
raise Timeout::Error, "Read Timeout"
|
106
|
+
end
|
107
|
+
rescue IOError, Errno::ENOTSOCK
|
108
|
+
# These can happen with the socket being closed while waiting on select
|
109
|
+
data = ''
|
65
110
|
end
|
66
|
-
rescue IOError, Errno::ENOTSOCK
|
67
|
-
# These can happen with the socket being closed while waiting on select
|
111
|
+
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError, Errno::ENOTSOCK
|
68
112
|
data = ''
|
69
113
|
end
|
70
|
-
rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError, Errno::ENOTSOCK
|
71
|
-
data = ''
|
72
114
|
end
|
73
115
|
|
74
116
|
data
|
@@ -79,9 +121,19 @@ module Cosmos
|
|
79
121
|
# No read mutex is needed because there is only one stream procesor
|
80
122
|
# reading
|
81
123
|
begin
|
82
|
-
|
83
|
-
|
84
|
-
|
124
|
+
if FAST_READ
|
125
|
+
data = @read_socket.read_nonblock(65535, exception: false)
|
126
|
+
raise EOFError, 'end of file reached' unless data
|
127
|
+
if data == :wait_readable
|
128
|
+
data = ''
|
129
|
+
else
|
130
|
+
@raw_logger_pair.read_logger.write(data) if @raw_logger_pair
|
131
|
+
end
|
132
|
+
else
|
133
|
+
data = @read_socket.read_nonblock(65535)
|
134
|
+
@raw_logger_pair.read_logger.write(data) if @raw_logger_pair
|
135
|
+
end
|
136
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNRESET, Errno::ECONNABORTED, IOError
|
85
137
|
data = ''
|
86
138
|
end
|
87
139
|
|
@@ -135,6 +187,7 @@ module Cosmos
|
|
135
187
|
def disconnect
|
136
188
|
Cosmos.close_socket(@write_socket)
|
137
189
|
Cosmos.close_socket(@read_socket)
|
190
|
+
@pipe_writer.write('.')
|
138
191
|
@connected = false
|
139
192
|
end
|
140
193
|
|
data/lib/cosmos/system/target.rb
CHANGED
@@ -107,6 +107,8 @@ module Cosmos
|
|
107
107
|
# If target.txt didn't specify specific cmd/tlm files then add everything
|
108
108
|
if @cmd_tlm_files.empty?
|
109
109
|
@cmd_tlm_files = add_all_cmd_tlm(@dir)
|
110
|
+
else
|
111
|
+
add_cmd_tlm_partials(@dir)
|
110
112
|
end
|
111
113
|
end
|
112
114
|
|
@@ -184,14 +186,26 @@ module Cosmos
|
|
184
186
|
def add_all_cmd_tlm(dir)
|
185
187
|
cmd_tlm_files = []
|
186
188
|
if Dir.exist?(File.join(dir, 'cmd_tlm'))
|
187
|
-
#
|
188
|
-
Dir[File.join(dir, 'cmd_tlm', '*.txt')].each do |filename|
|
189
|
+
# Grab All *.txt files in the cmd_tlm folder and subfolders
|
190
|
+
Dir[File.join(dir, 'cmd_tlm', '**', '*.txt')].each do |filename|
|
189
191
|
cmd_tlm_files << filename
|
190
192
|
end
|
191
193
|
end
|
192
194
|
cmd_tlm_files.sort!
|
193
195
|
end
|
194
196
|
|
197
|
+
# Make sure all partials are included in the cmd_tlm list for the MD5 calculation
|
198
|
+
def add_cmd_tlm_partials(dir)
|
199
|
+
if Dir.exist?(File.join(dir, 'cmd_tlm'))
|
200
|
+
# Grab all _*.txt files in the cmd_tlm folder and subfolders
|
201
|
+
Dir[File.join(dir, 'cmd_tlm', '**', '_*.txt')].each do |filename|
|
202
|
+
@cmd_tlm_files << filename
|
203
|
+
end
|
204
|
+
end
|
205
|
+
@cmd_tlm_files.uniq!
|
206
|
+
@cmd_tlm_files.sort!
|
207
|
+
end
|
208
|
+
|
195
209
|
end # class Target
|
196
210
|
|
197
211
|
end # module Cosmos
|
@@ -84,6 +84,24 @@ module Cosmos
|
|
84
84
|
initialize_menus()
|
85
85
|
initialize_central_widget()
|
86
86
|
complete_initialize() # defined in qt_tool
|
87
|
+
|
88
|
+
# Bring up slash screen for long duration tasks after creation
|
89
|
+
Splash.execute(self) do |splash|
|
90
|
+
# Configure CosmosConfig to interact with splash screen
|
91
|
+
ConfigParser.splash = splash
|
92
|
+
|
93
|
+
System.commands
|
94
|
+
Qt.execute_in_main_thread(true) do
|
95
|
+
update_targets()
|
96
|
+
@target_select.setCurrentText(options.packet[0]) if options.packet
|
97
|
+
update_commands()
|
98
|
+
@cmd_select.setCurrentText(options.packet[1]) if options.packet
|
99
|
+
update_cmd_params()
|
100
|
+
end
|
101
|
+
|
102
|
+
# Unconfigure CosmosConfig to interact with splash screen
|
103
|
+
ConfigParser.splash = nil
|
104
|
+
end
|
87
105
|
end
|
88
106
|
|
89
107
|
def initialize_actions
|
@@ -245,24 +263,8 @@ module Cosmos
|
|
245
263
|
layout.addWidget(splitter)
|
246
264
|
central_widget.layout = layout
|
247
265
|
|
248
|
-
#Mark this window as the window for popups
|
266
|
+
# Mark this window as the window for popups
|
249
267
|
set_cmd_tlm_gui_window(self)
|
250
|
-
|
251
|
-
# Bring up slash screen for long duration tasks after creation
|
252
|
-
Splash.execute(self) do |splash|
|
253
|
-
# Configure CosmosConfig to interact with splash screen
|
254
|
-
ConfigParser.splash = splash
|
255
|
-
|
256
|
-
System.commands
|
257
|
-
Qt.execute_in_main_thread(true) do
|
258
|
-
update_targets()
|
259
|
-
update_commands()
|
260
|
-
update_cmd_params()
|
261
|
-
end
|
262
|
-
|
263
|
-
# Unconfigure CosmosConfig to interact with splash screen
|
264
|
-
ConfigParser.splash = nil
|
265
|
-
end
|
266
268
|
end
|
267
269
|
|
268
270
|
def menu_states_in_hex(checked)
|
@@ -706,6 +708,15 @@ module Cosmos
|
|
706
708
|
options.width = 600
|
707
709
|
options.height = 425
|
708
710
|
options.title = 'Command Sender'
|
711
|
+
option_parser.separator "Command Sender Specific Options:"
|
712
|
+
option_parser.on("-p", "--packet 'TARGET_NAME PACKET_NAME'", "Start with the specified command selected") do |arg|
|
713
|
+
split = arg.split
|
714
|
+
if split.length != 2
|
715
|
+
puts "Packet must be specified as 'TARGET_NAME PACKET_NAME' in quotes"
|
716
|
+
exit
|
717
|
+
end
|
718
|
+
options.packet = split
|
719
|
+
end
|
709
720
|
end
|
710
721
|
|
711
722
|
super(option_parser, options)
|
@@ -79,15 +79,27 @@ module Cosmos
|
|
79
79
|
when 'PACKET_LOG_WRITER'
|
80
80
|
usage = "PACKET_LOG_WRITER <Name> <Filename> <Specific Parameters>"
|
81
81
|
parser.verify_num_parameters(2, nil, usage)
|
82
|
+
packet_log_writer_name = params[0].upcase
|
82
83
|
packet_log_writer_class = Cosmos.require_class(params[1])
|
84
|
+
|
85
|
+
# Verify not overridding a packet log writer that is already associated with an interface
|
86
|
+
packet_log_writer_pair = @packet_log_writer_pairs[packet_log_writer_name]
|
87
|
+
if packet_log_writer_pair
|
88
|
+
@interfaces.each do |interface_name, interface|
|
89
|
+
if interface.packet_log_writer_pairs.include?(packet_log_writer_pair)
|
90
|
+
raise parser.error("Redefining Packet Log Writer #{packet_log_writer_name} not allowed after it is associated with an interface")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
83
95
|
if params[2]
|
84
96
|
cmd_log_writer = packet_log_writer_class.new(:CMD, *params[2..-1])
|
85
97
|
tlm_log_writer = packet_log_writer_class.new(:TLM, *params[2..-1])
|
86
|
-
@packet_log_writer_pairs[
|
98
|
+
@packet_log_writer_pairs[packet_log_writer_name] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
|
87
99
|
else
|
88
100
|
cmd_log_writer = packet_log_writer_class.new(:CMD)
|
89
101
|
tlm_log_writer = packet_log_writer_class.new(:TLM)
|
90
|
-
@packet_log_writer_pairs[
|
102
|
+
@packet_log_writer_pairs[packet_log_writer_name] = PacketLogWriterPair.new(cmd_log_writer, tlm_log_writer)
|
91
103
|
end
|
92
104
|
|
93
105
|
when 'AUTO_INTERFACE_TARGETS'
|
@@ -179,7 +179,7 @@ module Cosmos
|
|
179
179
|
when 1
|
180
180
|
handle_tab('Targets') { @targets_tab.update }
|
181
181
|
when 2
|
182
|
-
handle_tab('
|
182
|
+
handle_tab('Commands') { @packets_tab.update(PacketsTab::COMMANDS) }
|
183
183
|
when 3
|
184
184
|
handle_tab('Telemetry') { @packets_tab.update(PacketsTab::TELEMETRY) }
|
185
185
|
when 4
|
@@ -76,12 +76,12 @@ module Cosmos
|
|
76
76
|
table = Qt::TableWidget.new()
|
77
77
|
table.verticalHeader.hide()
|
78
78
|
table.setRowCount(count)
|
79
|
-
column_cnt =
|
80
|
-
column_cnt += 1 if name == TELEMETRY
|
79
|
+
column_cnt = 5
|
81
80
|
table.setColumnCount(column_cnt)
|
82
81
|
# Force the last section to fill all available space in the frame
|
83
82
|
#~ table.horizontalHeader.setStretchLastSection(true)
|
84
83
|
headers = ["Target Name", "Packet Name", "Packet Count", "View Raw"]
|
84
|
+
headers << "View in Command Sender" if name == COMMANDS
|
85
85
|
headers << "View in Packet Viewer" if name == TELEMETRY
|
86
86
|
table.setHorizontalHeaderLabels(headers)
|
87
87
|
|
@@ -121,24 +121,10 @@ module Cosmos
|
|
121
121
|
end
|
122
122
|
table.setCellWidget(row, 3, view_raw)
|
123
123
|
|
124
|
-
if name ==
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
if Kernel.is_windows?
|
129
|
-
Cosmos.run_process("rubyw tools/PacketViewer -p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
|
130
|
-
elsif Kernel.is_mac? and File.exist?("tools/mac/PacketViewer.app")
|
131
|
-
Cosmos.run_process("open tools/mac/PacketViewer.app --args -p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
|
132
|
-
else
|
133
|
-
Cosmos.run_process("ruby tools/PacketViewer -p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
|
134
|
-
end
|
135
|
-
end
|
136
|
-
table.setCellWidget(row, 4, view_pv)
|
137
|
-
else
|
138
|
-
table_widget = Qt::TableWidgetItem.new(Qt::Object.tr('N/A'))
|
139
|
-
table_widget.setTextAlignment(Qt::AlignCenter)
|
140
|
-
table.setItem(row, 4, table_widget)
|
141
|
-
end
|
124
|
+
if name == COMMANDS
|
125
|
+
add_tool_button(table, row, target_name, packet_name, "Command Sender")
|
126
|
+
elsif name == TELEMETRY
|
127
|
+
add_tool_button(table, row, target_name, packet_name, "Packet Viewer")
|
142
128
|
end
|
143
129
|
|
144
130
|
row += 1
|
@@ -146,5 +132,26 @@ module Cosmos
|
|
146
132
|
end
|
147
133
|
end
|
148
134
|
|
135
|
+
def add_tool_button(table, row, target_name, packet_name, tool_name)
|
136
|
+
if target_name != 'UNKNOWN' and packet_name != 'UNKNOWN'
|
137
|
+
view_pv = Qt::PushButton.new("View in #{tool_name}")
|
138
|
+
view_pv.connect(SIGNAL('clicked()')) do
|
139
|
+
tool_name = tool_name.split.join.gsub("Command","Cmd") # remove space and convert name
|
140
|
+
if Kernel.is_windows?
|
141
|
+
Cosmos.run_process("rubyw tools/#{tool_name} -p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
|
142
|
+
elsif Kernel.is_mac? and File.exist?("tools/mac/#{tool_name}.app")
|
143
|
+
Cosmos.run_process("open tools/mac/#{tool_name}.app --args -p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
|
144
|
+
else
|
145
|
+
Cosmos.run_process("ruby tools/#{tool_name} -p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
table.setCellWidget(row, 4, view_pv)
|
149
|
+
else
|
150
|
+
table_widget = Qt::TableWidgetItem.new(Qt::Object.tr('N/A'))
|
151
|
+
table_widget.setTextAlignment(Qt::AlignCenter)
|
152
|
+
table.setItem(row, 4, table_widget)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
149
156
|
end
|
150
157
|
end # module Cosmos
|