cosmos 4.4.1 → 4.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_v4.yml +33 -0
  3. data/Dockerfile +10 -4
  4. data/Gemfile +1 -1
  5. data/Manifest.txt +26 -2
  6. data/README.md +4 -1
  7. data/Rakefile +33 -27
  8. data/autohotkey/tools/cmd_extractor.ahk +11 -9
  9. data/autohotkey/tools/cmd_sender.ahk +1 -1
  10. data/autohotkey/tools/cmd_sequence.ahk +1 -1
  11. data/autohotkey/tools/data_viewer.ahk +1 -1
  12. data/autohotkey/tools/limits_monitor.ahk +1 -1
  13. data/autohotkey/tools/packet_viewer.ahk +1 -1
  14. data/autohotkey/tools/script_runner.ahk +1 -1
  15. data/autohotkey/tools/test_runner2.ahk +1 -1
  16. data/autohotkey/tools/tlm_grapher.ahk +1 -1
  17. data/autohotkey/tools/tlm_grapher3.ahk +1 -1
  18. data/autohotkey/tools/tlm_viewer.ahk +1 -1
  19. data/autohotkey/tools/tlm_viewer2.ahk +1 -1
  20. data/autohotkey/tools/tlm_viewer5.ahk +1 -1
  21. data/bin/rubysloc +73 -28
  22. data/bin/xtce_converter +1 -1
  23. data/cosmos.gemspec +6 -12
  24. data/data/config/interface_modifiers.yaml +3 -2
  25. data/data/config/system.yaml +81 -24
  26. data/data/crc.txt +435 -435
  27. data/demo/Rakefile +4 -4
  28. data/demo/config/data/crc.txt +250 -250
  29. data/demo/config/system/system.txt +15 -7
  30. data/demo/config/system/system2.txt +15 -7
  31. data/demo/config/system/system_alt_ports.txt +15 -7
  32. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -1
  33. data/demo/config/tools/handbook_creator/default_toc.xsl +59 -59
  34. data/ext/cosmos/ext/buffered_file/buffered_file.c +2 -2
  35. data/ext/cosmos/ext/config_parser/config_parser.c +1 -2
  36. data/ext/cosmos/ext/line_graph/line_graph.c +53 -94
  37. data/ext/cosmos/ext/packet/packet.c +0 -6
  38. data/ext/cosmos/ext/platform/platform.c +56 -21
  39. data/ext/cosmos/ext/polynomial_conversion/polynomial_conversion.c +4 -8
  40. data/ext/cosmos/ext/structure/structure.c +12 -0
  41. data/extensions/vscode/.gitignore +4 -0
  42. data/extensions/vscode/.vscode/launch.json +32 -0
  43. data/extensions/vscode/.vscode/settings.json +13 -0
  44. data/extensions/vscode/.vscode/tasks.json +79 -0
  45. data/extensions/vscode/License.txt +879 -0
  46. data/extensions/vscode/README.md +9 -0
  47. data/extensions/vscode/client/License.txt +879 -0
  48. data/extensions/vscode/client/README.md +39 -0
  49. data/extensions/vscode/client/cosmos.configuration.json +23 -0
  50. data/extensions/vscode/client/images/icon.png +0 -0
  51. data/extensions/vscode/client/package-lock.json +414 -0
  52. data/extensions/vscode/client/package.json +105 -0
  53. data/extensions/vscode/client/src/extension.ts +132 -0
  54. data/extensions/vscode/client/src/screen_preview.rb +25 -0
  55. data/extensions/vscode/client/syntaxes/cosmos.tmLanguage.json +219 -0
  56. data/extensions/vscode/client/tsconfig.json +17 -0
  57. data/extensions/vscode/package-lock.json +26 -0
  58. data/extensions/vscode/package.json +35 -0
  59. data/extensions/vscode/server/License.txt +879 -0
  60. data/extensions/vscode/server/package-lock.json +236 -0
  61. data/extensions/vscode/server/package.json +29 -0
  62. data/extensions/vscode/server/src/server.ts +59 -0
  63. data/extensions/vscode/server/tsconfig.json +16 -0
  64. data/install/Rakefile +4 -4
  65. data/install/config/data/crc.txt +145 -145
  66. data/install/config/system/system.txt +15 -7
  67. data/install/config/tools/handbook_creator/default_toc.xsl +59 -59
  68. data/lib/cosmos/config/config_parser.rb +2 -10
  69. data/lib/cosmos/core_ext/class.rb +10 -0
  70. data/lib/cosmos/core_ext/time.rb +5 -3
  71. data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
  72. data/lib/cosmos/dart/lib/dart_common.rb +3 -3
  73. data/lib/cosmos/dart/lib/dart_decommutator.rb +4 -4
  74. data/lib/cosmos/dart/processes/dart_decom_server.rb +1 -1
  75. data/lib/cosmos/dart/processes/dart_master.rb +1 -1
  76. data/lib/cosmos/dart/spec/dart/dart_database_cleaner_spec.rb +2 -2
  77. data/lib/cosmos/gui/qt.rb +10 -10
  78. data/lib/cosmos/gui/qt_tool.rb +17 -12
  79. data/lib/cosmos/gui/text/completion_text_edit.rb +2 -0
  80. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +1 -1
  81. data/lib/cosmos/interfaces/dart_status_interface.rb +1 -1
  82. data/lib/cosmos/interfaces/linc_interface.rb +3 -3
  83. data/lib/cosmos/interfaces/protocols/burst_protocol.rb +1 -1
  84. data/lib/cosmos/interfaces/protocols/crc_protocol.rb +1 -1
  85. data/lib/cosmos/interfaces/protocols/template_protocol.rb +3 -3
  86. data/lib/cosmos/interfaces/serial_interface.rb +7 -1
  87. data/lib/cosmos/interfaces/stream_interface.rb +1 -1
  88. data/lib/cosmos/interfaces/tcpip_server_interface.rb +16 -16
  89. data/lib/cosmos/io/io_multiplexer.rb +6 -2
  90. data/lib/cosmos/io/json_drb.rb +3 -11
  91. data/lib/cosmos/io/json_drb_object.rb +7 -2
  92. data/lib/cosmos/io/json_drb_rack.rb +25 -5
  93. data/lib/cosmos/io/json_rpc.rb +1 -1
  94. data/lib/cosmos/io/posix_serial_driver.rb +60 -22
  95. data/lib/cosmos/io/serial_driver.rb +11 -8
  96. data/lib/cosmos/io/win32_serial_driver.rb +8 -1
  97. data/lib/cosmos/packets/packet.rb +8 -8
  98. data/lib/cosmos/packets/packet_config.rb +1 -1
  99. data/lib/cosmos/packets/packet_item_limits.rb +2 -14
  100. data/lib/cosmos/packets/parsers/xtce_converter.rb +10 -10
  101. data/lib/cosmos/packets/parsers/xtce_parser.rb +3 -0
  102. data/lib/cosmos/packets/structure.rb +18 -5
  103. data/lib/cosmos/packets/structure_item.rb +4 -21
  104. data/lib/cosmos/script/api_shared.rb +18 -1
  105. data/lib/cosmos/script/extract.rb +1 -1
  106. data/lib/cosmos/script/script.rb +4 -11
  107. data/lib/cosmos/streams/serial_stream.rb +11 -6
  108. data/lib/cosmos/system/system.rb +47 -13
  109. data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +15 -0
  110. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +25 -3
  111. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +7 -0
  112. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +0 -5
  113. data/lib/cosmos/tools/cmd_tlm_server/api.rb +10 -8
  114. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +2 -2
  115. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +1 -1
  116. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +29 -26
  117. data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +1 -1
  118. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +5 -0
  119. data/lib/cosmos/tools/config_editor/config_editor.rb +1 -1
  120. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +1 -1
  121. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +1 -1
  122. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +5 -2
  123. data/lib/cosmos/tools/test_runner/test.rb +1 -1
  124. data/lib/cosmos/tools/test_runner/test_runner.rb +4 -4
  125. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +3 -3
  126. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -4
  127. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +3 -3
  128. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +1 -1
  129. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +2 -2
  130. data/lib/cosmos/tools/tlm_viewer/widgets/canvasdot_widget.rb +2 -0
  131. data/lib/cosmos/top_level.rb +1 -1
  132. data/lib/cosmos/utilities/simulated_target.rb +1 -1
  133. data/lib/cosmos/version.rb +5 -5
  134. data/make_gems.sh +1 -1
  135. data/spec/core_ext/class_spec.rb +54 -0
  136. data/spec/core_ext/time_spec.rb +4 -0
  137. data/spec/gui/qt_spec.rb +1 -1
  138. data/spec/gui/utilities/script_module_gui_spec.rb +1 -1
  139. data/spec/interfaces/linc_interface_spec.rb +1 -1
  140. data/spec/interfaces/serial_interface_spec.rb +1 -5
  141. data/spec/io/json_drb_rack_spec.rb +166 -0
  142. data/spec/io/json_rpc_spec.rb +4 -5
  143. data/spec/io/posix_serial_driver_spec.rb +87 -0
  144. data/spec/io/win32_serial_driver_spec.rb +17 -1
  145. data/spec/packet_logs/packet_log_reader_spec.rb +34 -35
  146. data/spec/packets/packet_item_limits_spec.rb +6 -33
  147. data/spec/packets/structure_item_spec.rb +3 -21
  148. data/spec/script/extract_spec.rb +4 -1
  149. data/spec/system/system_spec.rb +109 -1
  150. data/spec/tools/cmd_tlm_server/api_spec.rb +12 -12
  151. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +2 -2
  152. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +4 -3
  153. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
  154. data/spec/top_level/top_level_spec.rb +2 -2
  155. data/spec/utilities/logger_spec.rb +3 -3
  156. data/test/performance/Rakefile +4 -4
  157. data/test/performance/config/data/crc.txt +67 -48
  158. metadata +59 -9
  159. data/.coveralls.yml +0 -1
  160. data/.travis.yml +0 -16
@@ -25,19 +25,20 @@ module Cosmos
25
25
  write_timeout = 10.0,
26
26
  read_timeout = nil,
27
27
  flow_control = :NONE,
28
- data_bits = 8)
28
+ data_bits = 8,
29
+ struct = [])
29
30
 
30
31
  # Convert Baud Rate into Termios constant
31
32
  begin
32
33
  baud_rate = Object.const_get("Termios::B#{baud_rate}")
33
34
  rescue NameError
34
- raise(ArgumentError, "Invalid Baud Rate, Not Defined by Termios: #{baud_rate}")
35
+ raise(ArgumentError, "Invalid baud rate: #{baud_rate}")
35
36
  end
36
37
 
37
38
  # Verify Parameters
38
- raise(ArgumentError, "Invalid Data Bits: #{data_bits}") unless [5,6,7,8].include?(data_bits)
39
+ raise(ArgumentError, "Invalid data bits: #{data_bits}") unless [5,6,7,8].include?(data_bits)
39
40
  raise(ArgumentError, "Invalid parity: #{parity}") if parity and !SerialDriver::VALID_PARITY.include?(parity)
40
- raise(ArgumentError, "Invalid Stop Bits: #{stop_bits}") unless [1,2].include?(stop_bits)
41
+ raise(ArgumentError, "Invalid stop bits: #{stop_bits}") unless [1,2].include?(stop_bits)
41
42
  @write_timeout = write_timeout
42
43
  @read_timeout = read_timeout
43
44
 
@@ -51,22 +52,61 @@ module Cosmos
51
52
 
52
53
  # Configure the serial Port
53
54
  tio = Termios::new_termios()
54
- iflags = 0
55
- iflags |= Termios::IGNPAR unless parity
56
- cflags = 0
57
- cflags |= Termios::CREAD # Enable receiver
58
- cflags |= Termios.const_get("CS#{data_bits}") # data bits
59
- cflags |= Termios::CLOCAL # Ignore Modem Control Lines
60
- cflags |= Termios::CSTOPB if stop_bits == 2
61
- cflags |= Termios::PARENB if parity
62
- cflags |= Termios::PARODD if parity == :ODD
63
- cflags |= Termios::CRTSCTS if flow_control == :RTSCTS
64
- tio.iflag = iflags
65
- tio.oflag = 0
66
- tio.cflag = cflags
67
- tio.lflag = 0
55
+ iflag = 0
56
+ iflag |= Termios::IGNPAR unless parity
57
+ oflag = 0
58
+ cflag = 0
59
+ cflag |= Termios::CREAD # Enable receiver
60
+ cflag |= Termios.const_get("CS#{data_bits}") # data bits
61
+ cflag |= Termios::CLOCAL # Ignore Modem Control Lines
62
+ cflag |= Termios::CSTOPB if stop_bits == 2
63
+ cflag |= Termios::PARENB if parity
64
+ cflag |= Termios::PARODD if parity == :ODD
65
+ cflag |= Termios::CRTSCTS if flow_control == :RTSCTS
66
+ lflag = 0
68
67
  tio.cc[Termios::VTIME] = 0
69
68
  tio.cc[Termios::VMIN] = 1
69
+ unless struct.empty?
70
+ struct.each do |field, key, value|
71
+ case field
72
+ when 'iflag'
73
+ if value == "0"
74
+ iflag &= ~Termios.const_get(key)
75
+ else
76
+ iflag |= Termios.const_get(key)
77
+ end
78
+ when 'oflag'
79
+ if value == "0"
80
+ oflag &= ~Termios.const_get(key)
81
+ else
82
+ oflag |= Termios.const_get(key)
83
+ end
84
+ when 'cflag'
85
+ if value == "0"
86
+ cflag &= ~Termios.const_get(key)
87
+ else
88
+ cflag |= Termios.const_get(key)
89
+ end
90
+ when 'lflag'
91
+ if value == "0"
92
+ lflag &= ~Termios.const_get(key)
93
+ else
94
+ lflag |= Termios.const_get(key)
95
+ end
96
+ when 'cc'
97
+ begin
98
+ value = Integer(value) # Try to convert to int
99
+ rescue ArgumentError
100
+ # Ignore this error and use the string
101
+ end
102
+ tio.cc[Termios.const_get(key)] = value
103
+ end
104
+ end
105
+ end
106
+ tio.iflag = iflag
107
+ tio.oflag = oflag
108
+ tio.cflag = cflag
109
+ tio.lflag = lflag
70
110
  tio.ispeed = baud_rate
71
111
  tio.ospeed = baud_rate
72
112
  @handle.tcflush(Termios::TCIOFLUSH)
@@ -143,7 +183,5 @@ module Cosmos
143
183
 
144
184
  data
145
185
  end
146
-
147
- end # class PosixSerialDriver
148
-
149
- end # module Cosmos
186
+ end
187
+ end
@@ -32,8 +32,10 @@ module Cosmos
32
32
  # complete or nil to block
33
33
  # @param read_timeout [Float|nil] Number of seconds to wait for the read to
34
34
  # complete or nil to block
35
- # @param flow_control [Symbol] Currently supported :NONE and :RTSCTS (default :NONE)
35
+ # @param flow_control [Symbol] Currently supported :NONE, :RTSCTS (default :NONE)
36
36
  # @param data_bits [Integer] Number of data bits (default 8)
37
+ # @param struct [Array] Array of arrays of fields and values to set in the
38
+ # Windows DCB or POSIX structure
37
39
  def initialize(port_name,
38
40
  baud_rate,
39
41
  parity = :NONE,
@@ -41,7 +43,8 @@ module Cosmos
41
43
  write_timeout = 10.0,
42
44
  read_timeout = nil,
43
45
  flow_control = :NONE,
44
- data_bits = 8)
46
+ data_bits = 8,
47
+ struct = [])
45
48
  raise(ArgumentError, "Invalid parity: #{parity}") unless VALID_PARITY.include? parity
46
49
  if Kernel.is_windows?
47
50
  @driver = Win32SerialDriver.new(port_name,
@@ -53,7 +56,8 @@ module Cosmos
53
56
  0.01,
54
57
  1000,
55
58
  flow_control,
56
- data_bits)
59
+ data_bits,
60
+ struct)
57
61
  elsif RUBY_ENGINE == 'ruby'
58
62
  @driver = PosixSerialDriver.new(port_name,
59
63
  baud_rate,
@@ -62,7 +66,8 @@ module Cosmos
62
66
  write_timeout,
63
67
  read_timeout,
64
68
  flow_control,
65
- data_bits)
69
+ data_bits,
70
+ struct)
66
71
  else
67
72
  @driver = nil # JRuby Serial on Linux not currently supported
68
73
  end
@@ -92,7 +97,5 @@ module Cosmos
92
97
  def read_nonblock
93
98
  @driver.read_nonblock
94
99
  end
95
-
96
- end # class SerialDriver
97
-
98
- end # module Cosmos
100
+ end
101
+ end
@@ -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:
@@ -186,9 +186,9 @@ module Cosmos
186
186
  @read_conversion_cache.clear if @read_conversion_cache
187
187
  @received_count
188
188
  end
189
-
190
- end # if RUBY_ENGINE != 'ruby' or ENV['COSMOS_NO_EXT']
191
-
189
+
190
+ end # if RUBY_ENGINE != 'ruby' or ENV['COSMOS_NO_EXT']
191
+
192
192
  # Tries to identify if a buffer represents the currently defined packet. It
193
193
  # does this by iterating over all the packet items that were created with
194
194
  # an ID value and checking whether that ID value is present at the correct
@@ -216,7 +216,7 @@ module Cosmos
216
216
 
217
217
  true
218
218
  end
219
-
219
+
220
220
  # Reads the values from a buffer at the position of each id_item defined
221
221
  # in the packet.
222
222
  #
@@ -226,7 +226,7 @@ module Cosmos
226
226
  return [] unless buffer
227
227
  return [] unless @id_items
228
228
  values = []
229
-
229
+
230
230
  @id_items.each do |item|
231
231
  begin
232
232
  values << read_item(item, :RAW, buffer)
@@ -234,10 +234,10 @@ module Cosmos
234
234
  values << nil
235
235
  end
236
236
  end
237
-
237
+
238
238
  values
239
239
  end
240
-
240
+
241
241
  # Returns @received_time unless a packet item called PACKET_TIME exists that returns
242
242
  # a Ruby Time object that represents a different timestamp for the packet
243
243
  def packet_time
@@ -259,7 +259,7 @@ module Cosmos
259
259
  end
260
260
 
261
261
  # Use the hashing algorithm established by Cosmos::System
262
- digest = Digest.const_get(System.hashing_algorithm).send('new')
262
+ digest = Digest.const_get(System.hashing_algorithm).public_send('new')
263
263
  digest << string
264
264
  @config_name = digest.hexdigest
265
265
  @config_name
@@ -443,7 +443,7 @@ module Cosmos
443
443
  klass = params[0].filename_to_class_name.to_class
444
444
  raise parser.error("#{params[0].filename_to_class_name} class not found. Did you require the file in target.txt?", usage) unless klass
445
445
  conversion = klass.new(*params[1..(params.length - 1)])
446
- @current_item.send("#{keyword.downcase}=".to_sym, conversion)
446
+ @current_item.public_send("#{keyword.downcase}=".to_sym, conversion)
447
447
  if klass != ProcessorConversion and (conversion.converted_type.nil? or conversion.converted_bit_size.nil?)
448
448
  msg = "Read Conversion #{params[0].filename_to_class_name} on item #{@current_item.name} does not specify converted type or bit size. Will not be supported by DART"
449
449
  @warnings << msg
@@ -91,24 +91,12 @@ module Cosmos
91
91
  end
92
92
 
93
93
  def persistence_setting=(persistence_setting)
94
- if 0.class == Integer
95
- # Ruby version >= 2.4.0
96
- raise ArgumentError, "persistence_setting must be an Integer but is a #{persistence_setting.class}" unless Integer === persistence_setting
97
- else
98
- # Ruby version < 2.4.0
99
- raise ArgumentError, "persistence_setting must be a Fixnum but is a #{persistence_setting.class}" unless Fixnum === persistence_setting
100
- end
94
+ raise ArgumentError, "persistence_setting must be an Integer but is a #{persistence_setting.class}" unless Integer === persistence_setting
101
95
  @persistence_setting = persistence_setting
102
96
  end
103
97
 
104
98
  def persistence_count=(persistence_count)
105
- if 0.class == Integer
106
- # Ruby version >= 2.4.0
107
- raise ArgumentError, "persistence_count must be an Integer but is a #{persistence_count.class}" unless Integer === persistence_count
108
- else
109
- # Ruby version < 2.4.0
110
- raise ArgumentError, "persistence_count must be a Fixnum but is a #{persistence_count.class}" unless Fixnum === persistence_count
111
- end
99
+ raise ArgumentError, "persistence_count must be an Integer but is a #{persistence_count.class}" unless Integer === persistence_count
112
100
  @persistence_count = persistence_count
113
101
  end
114
102
 
@@ -196,7 +196,7 @@ module Cosmos
196
196
  # TODO: Handle nonunique item names
197
197
  if item.array_size
198
198
  # Requiring parameterRef for argument arrays appears to be a defect in the schema
199
- xml['xtce'].send("Array#{type}RefEntry".intern, :parameterRef => item.name) do
199
+ xml['xtce'].public_send("Array#{type}RefEntry".intern, :parameterRef => item.name) do
200
200
  set_fixed_value(xml, item) if !packed
201
201
  xml['xtce'].DimensionList do
202
202
  xml['xtce'].Dimension do
@@ -211,9 +211,9 @@ module Cosmos
211
211
  end
212
212
  else
213
213
  if packed
214
- xml['xtce'].send("#{type}RefEntry".intern, "#{type.downcase}Ref".intern => item.name)
214
+ xml['xtce'].public_send("#{type}RefEntry".intern, "#{type.downcase}Ref".intern => item.name)
215
215
  else
216
- xml['xtce'].send("#{type}RefEntry".intern, "#{type.downcase}Ref".intern => item.name) do
216
+ xml['xtce'].public_send("#{type}RefEntry".intern, "#{type.downcase}Ref".intern => item.name) do
217
217
  set_fixed_value(xml, item)
218
218
  end
219
219
  end
@@ -256,7 +256,7 @@ module Cosmos
256
256
  attrs[:shortDescription] = item.description if item.description
257
257
  attrs[:arrayTypeRef] = (item.name + '_Type')
258
258
  attrs[:numberOfDimensions] = '1' # COSMOS Only supports one-dimensional arrays
259
- xml['xtce'].send('Array' + param_or_arg + 'Type', attrs)
259
+ xml['xtce'].public_send('Array' + param_or_arg + 'Type', attrs)
260
260
  end
261
261
  end
262
262
 
@@ -289,7 +289,7 @@ module Cosmos
289
289
  encoding = 'unsigned'
290
290
  end
291
291
  if item.states
292
- xml['xtce'].send('Enumerated' + param_or_arg + 'Type', attrs) do
292
+ xml['xtce'].public_send('Enumerated' + param_or_arg + 'Type', attrs) do
293
293
  to_xtce_endianness(item, xml)
294
294
  to_xtce_units(item, xml)
295
295
  xml['xtce'].IntegerDataEncoding(:sizeInBits => item.bit_size, :encoding => encoding)
@@ -308,7 +308,7 @@ module Cosmos
308
308
  type_string = 'Integer' + param_or_arg + 'Type'
309
309
  attrs[:signed] = signed
310
310
  end
311
- xml['xtce'].send(type_string, attrs) do
311
+ xml['xtce'].public_send(type_string, attrs) do
312
312
  to_xtce_endianness(item, xml)
313
313
  to_xtce_units(item, xml)
314
314
  if (item.read_conversion and item.read_conversion.class == PolynomialConversion) or (item.write_conversion and item.write_conversion.class == PolynomialConversion)
@@ -330,7 +330,7 @@ module Cosmos
330
330
  attrs = { :name => (item.name + '_Type'), :sizeInBits => item.bit_size }
331
331
  attrs[:initialValue] = item.default if item.default and !item.array_size
332
332
  attrs[:shortDescription] = item.description if item.description
333
- xml['xtce'].send('Float' + param_or_arg + 'Type', attrs) do
333
+ xml['xtce'].public_send('Float' + param_or_arg + 'Type', attrs) do
334
334
  to_xtce_endianness(item, xml)
335
335
  to_xtce_units(item, xml)
336
336
  if (item.read_conversion and item.read_conversion.class == PolynomialConversion) or (item.write_conversion and item.write_conversion.class == PolynomialConversion)
@@ -359,7 +359,7 @@ module Cosmos
359
359
  end
360
360
  end
361
361
  attrs[:shortDescription] = item.description if item.description
362
- xml['xtce'].send(string_or_binary + param_or_arg + 'Type', attrs) do
362
+ xml['xtce'].public_send(string_or_binary + param_or_arg + 'Type', attrs) do
363
363
  # Don't call to_xtce_endianness for Strings or Blocks
364
364
  to_xtce_units(item, xml)
365
365
  if string_or_binary == 'String'
@@ -382,9 +382,9 @@ module Cosmos
382
382
 
383
383
  def to_xtce_item(item, param_or_arg, xml)
384
384
  if item.array_size
385
- xml['xtce'].send(param_or_arg, :name => item.name, "#{param_or_arg.downcase}TypeRef" => item.name + '_ArrayType')
385
+ xml['xtce'].public_send(param_or_arg, :name => item.name, "#{param_or_arg.downcase}TypeRef" => item.name + '_ArrayType')
386
386
  else
387
- xml['xtce'].send(param_or_arg, :name => item.name, "#{param_or_arg.downcase}TypeRef" => item.name + '_Type')
387
+ xml['xtce'].public_send(param_or_arg, :name => item.name, "#{param_or_arg.downcase}TypeRef" => item.name + '_Type')
388
388
  end
389
389
  end
390
390
 
@@ -59,6 +59,9 @@ module Cosmos
59
59
  end
60
60
 
61
61
  def parse(filename, target_name)
62
+ # Fortify complains about Path Manipulation here
63
+ # We have previously validated the file is a .xtce file in packet_config
64
+ # The file is opened read-only and then immediately parsed by Nokogiri
62
65
  doc = File.open(filename) { |f| Nokogiri::XML(f, nil, nil, Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NOBLANKS) }
63
66
  # Determine the @current_target_name
64
67
  xtce_process_element(doc.root)
@@ -462,12 +462,14 @@ module Cosmos
462
462
  extend(MethodMissing)
463
463
  end
464
464
 
465
- protected
466
-
467
465
  # Take the structure mutex to ensure the buffer does not change while you perform activities
468
466
  def synchronize
469
- @mutex ||= Mutex.new
470
- @mutex.synchronize {|| yield}
467
+ setup_mutex()
468
+ if @mutex.owned?
469
+ yield
470
+ else
471
+ @mutex.synchronize {|| yield}
472
+ end
471
473
  end
472
474
 
473
475
  # Take the structure mutex to ensure the buffer does not change while you perform activities
@@ -476,7 +478,7 @@ module Cosmos
476
478
  # lower level calls to go forward without getting the mutex
477
479
  def synchronize_allow_reads(top = false)
478
480
  @mutex_allow_reads ||= false
479
- @mutex ||= Mutex.new
481
+ setup_mutex()
480
482
  if top
481
483
  @mutex.synchronize do
482
484
  @mutex_allow_reads = Thread.current
@@ -500,6 +502,17 @@ module Cosmos
500
502
  end
501
503
  end
502
504
 
505
+ protected
506
+
507
+ MUTEX = Mutex.new
508
+
509
+ def setup_mutex
510
+ return if @mutex
511
+ MUTEX.synchronize do
512
+ @mutex ||= Mutex.new
513
+ end
514
+ end
515
+
503
516
  module MethodMissing
504
517
  # Method missing provides reading/writing item values as if they were methods to the class
505
518
  def method_missing(name, value = nil)
@@ -112,13 +112,7 @@ module Cosmos
112
112
  end
113
113
 
114
114
  def bit_offset=(bit_offset)
115
- if 0.class == Integer
116
- # Ruby version >= 2.4.0
117
- raise ArgumentError, "#{@name}: bit_offset must be an Integer" unless Integer === bit_offset
118
- else
119
- # Ruby version < 2.4.0
120
- raise ArgumentError, "#{@name}: bit_offset must be a Fixnum" unless Fixnum === bit_offset
121
- end
115
+ raise ArgumentError, "#{@name}: bit_offset must be an Integer" unless Integer === bit_offset
122
116
 
123
117
  byte_aligned = ((bit_offset % 8) == 0)
124
118
  if (@data_type == :FLOAT or @data_type == :STRING or @data_type == :BLOCK) and !byte_aligned
@@ -133,13 +127,8 @@ module Cosmos
133
127
  end
134
128
 
135
129
  def bit_size=(bit_size)
136
- if 0.class == Integer
137
- # Ruby version >= 2.4.0
138
- raise ArgumentError, "#{name}: bit_size must be an Integer" unless Integer === bit_size
139
- else
140
- # Ruby version < 2.4.0
141
- raise ArgumentError, "#{name}: bit_size must be a Fixnum" unless Fixnum === bit_size
142
- end
130
+ raise ArgumentError, "#{name}: bit_size must be an Integer" unless Integer === bit_size
131
+
143
132
  byte_multiple = ((bit_size % 8) == 0)
144
133
  if bit_size <= 0 and (@data_type == :INT or @data_type == :UINT or @data_type == :FLOAT)
145
134
  raise ArgumentError, "#{@name}: bit_size cannot be negative or zero for :INT, :UINT, and :FLOAT items: #{bit_size}"
@@ -171,13 +160,7 @@ module Cosmos
171
160
 
172
161
  def array_size=(array_size)
173
162
  if array_size
174
- if 0.class == Integer
175
- # Ruby version >= 2.4.0
176
- raise ArgumentError, "#{@name}: array_size must be an Integer" unless Integer === array_size
177
- else
178
- # Ruby version < 2.4.0
179
- raise ArgumentError, "#{@name}: array_size must be a Fixnum" unless Fixnum === array_size
180
- end
163
+ raise ArgumentError, "#{@name}: array_size must be an Integer" unless Integer === array_size
181
164
  raise ArgumentError, "#{@name}: array_size must be a multiple of bit_size" unless (@bit_size == 0 or (array_size % @bit_size == 0) or array_size < 0)
182
165
  raise ArgumentError, "#{@name}: bit_size cannot be negative or zero for array items" if @bit_size <= 0
183
166
  end
@@ -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
 
@@ -825,6 +832,8 @@ module Cosmos
825
832
  while true
826
833
  work_start = Time.now.sys
827
834
  value = tlm_variable(target_name, packet_name, item_name, value_type)
835
+ # Fortify: Dynamic Code Evaluation: Code Injection
836
+ # TODO: Is there anyway to sanitize the exp_to_eval?
828
837
  if eval(exp_to_eval)
829
838
  return true, value
830
839
  end
@@ -839,6 +848,8 @@ module Cosmos
839
848
 
840
849
  if canceled
841
850
  value = tlm_variable(target_name, packet_name, item_name, value_type)
851
+ # Fortify: Dynamic Code Evaluation: Code Injection
852
+ # TODO: Is there anyway to sanitize the exp_to_eval?
842
853
  if eval(exp_to_eval)
843
854
  return true, value
844
855
  else
@@ -879,6 +890,8 @@ module Cosmos
879
890
 
880
891
  while true
881
892
  work_start = Time.now.sys
893
+ # Fortify: Dynamic Code Evaluation: Code Injection
894
+ # TODO: Is there anyway to sanitize the exp_to_eval?
882
895
  if eval(exp_to_eval, context)
883
896
  return true
884
897
  end
@@ -892,6 +905,8 @@ module Cosmos
892
905
  canceled = cosmos_script_sleep(sleep_time)
893
906
 
894
907
  if canceled
908
+ # Fortify: Dynamic Code Evaluation: Code Injection
909
+ # TODO: Is there anyway to sanitize the exp_to_eval?
895
910
  if eval(exp_to_eval, context)
896
911
  return true
897
912
  else
@@ -907,6 +922,8 @@ module Cosmos
907
922
  string = "value " + comparison_to_eval
908
923
  check_str = "CHECK: #{_upcase(target_name, packet_name, item_name)} #{comparison_to_eval}"
909
924
  value_str = "with value == #{value}"
925
+ # Fortify: Dynamic Code Evaluation: Code Injection
926
+ # TODO: Is there anyway to sanitize the comparison_to_eval?
910
927
  if eval(string)
911
928
  Logger.info "#{check_str} success #{value_str}"
912
929
  else
@@ -942,7 +959,7 @@ module Cosmos
942
959
  end
943
960
 
944
961
  def run_tlm_viewer(action, display_name = '')
945
- tlm_viewer = JsonDRbObject.new System.connect_hosts['TLMVIEWER_API'], System.ports['TLMVIEWER_API']
962
+ tlm_viewer = JsonDRbObject.new System.connect_hosts['TLMVIEWER_API'], System.ports['TLMVIEWER_API'], 1.0, Cosmos::System.x_csrf_token
946
963
  begin
947
964
  yield tlm_viewer
948
965
  tlm_viewer.disconnect
@@ -130,7 +130,7 @@ module Cosmos
130
130
  return [target_name, packet_name, item_name, comparison_to_eval] if split_string.length == 3
131
131
  raise "ERROR: Check improperly specified: #{text}" if split_string.length < 4
132
132
  split_string = text.split(/ /) # Split on regex spaces to preserve spaces in comparison
133
- index = split_string.index(item_name)
133
+ index = split_string.rindex(item_name)
134
134
  comparison_to_eval = split_string[(index + 1)..(split_string.length - 1)].join(" ")
135
135
  raise "ERROR: Use '==' instead of '=': #{text}" if split_string[3] == '='
136
136
  return [target_name, packet_name, item_name, comparison_to_eval]
@@ -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
 
@@ -69,7 +62,7 @@ module Cosmos
69
62
  @cmd_tlm_server.disconnect
70
63
  else
71
64
  if $disconnect_all_targets
72
- return @disconnected.send(method_name, *method_params)
65
+ return @disconnected.public_send(method_name, *method_params)
73
66
  elsif $disconnected_targets
74
67
  name_string = nil
75
68
  if method_params[0].is_a?(String)
@@ -86,7 +79,7 @@ module Cosmos
86
79
  if name_string
87
80
  target = name_string.split(" ")[0]
88
81
  if $disconnected_targets.include?(target)
89
- return @disconnected.send(method_name, *method_params)
82
+ return @disconnected.public_send(method_name, *method_params)
90
83
  end
91
84
  end
92
85
  end
@@ -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 and :RTSCTS (default :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 # class SerialStream
155
- end # module Cosmos
159
+ end
160
+ end