cosmos 3.5.3 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|