cosmos 4.4.0-java → 4.4.1-java

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +6 -6
  5. data/Dockerfile +65 -0
  6. data/Manifest.txt +12 -2
  7. data/README.md +5 -0
  8. data/Rakefile +52 -0
  9. data/appveyor.yml +18 -8
  10. data/autohotkey/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  11. data/autohotkey/lib/cmd_sequence_exporter.rb +52 -0
  12. data/autohotkey/procedures/collect.rb +2 -2
  13. data/autohotkey/procedures/collect_util.rb +1 -1
  14. data/autohotkey/procedures/script_test.rb +1 -1
  15. data/autohotkey/tools/CmdSenderAHK2 +18 -0
  16. data/autohotkey/tools/cmd_sender.ahk +34 -6
  17. data/autohotkey/tools/cmd_sender2.ahk +4 -0
  18. data/autohotkey/tools/cmd_sequence.ahk +21 -8
  19. data/autohotkey/tools/config_editor.ahk +4 -4
  20. data/bin/cstol_converter +1 -1
  21. data/cosmos.gemspec +1 -1
  22. data/data/config/command_modifiers.yaml +16 -1
  23. data/data/config/param_item_modifiers.yaml +5 -0
  24. data/data/config/system.yaml +31 -1
  25. data/data/config/telemetry_modifiers.yaml +16 -1
  26. data/data/crc.txt +415 -410
  27. data/demo/config/dart/Gemfile +1 -6
  28. data/demo/config/data/crc.txt +244 -243
  29. data/demo/config/system/system.txt +3 -0
  30. data/demo/config/system/system2.txt +3 -0
  31. data/demo/config/system/system_alt_ports.txt +3 -0
  32. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +3 -3
  33. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +4 -0
  34. data/demo/config/targets/INST/cmd_tlm/inst_tlm_override.txt +12 -0
  35. data/demo/config/targets/INST/lib/sim_inst.rb +2 -2
  36. data/demo/config/targets/INST/target.txt +1 -0
  37. data/demo/procedures/cosmos_api_test.rb +8 -8
  38. data/install/config/dart/Gemfile +2 -7
  39. data/install/config/data/crc.txt +143 -143
  40. data/install/config/system/system.txt +3 -0
  41. data/lib/cosmos/dart/config/boot.rb +1 -1
  42. data/lib/cosmos/dart/config/database.yml +2 -0
  43. data/lib/cosmos/dart/lib/dart_common.rb +11 -4
  44. data/lib/cosmos/dart/lib/dart_constants.rb +15 -0
  45. data/lib/cosmos/dart/lib/dart_decom_query.rb +5 -6
  46. data/lib/cosmos/dart/lib/dart_decommutator.rb +66 -56
  47. data/lib/cosmos/dart/lib/dart_master_query.rb +71 -0
  48. data/lib/cosmos/dart/lib/dart_reducer_worker_thread.rb +165 -134
  49. data/lib/cosmos/dart/processes/dart.rb +4 -2
  50. data/lib/cosmos/dart/processes/dart_decom_server.rb +2 -2
  51. data/lib/cosmos/dart/processes/dart_ingester.rb +38 -1
  52. data/lib/cosmos/dart/processes/dart_master.rb +44 -0
  53. data/lib/cosmos/dart/processes/dart_util.rb +115 -0
  54. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +21 -2
  55. data/lib/cosmos/interfaces/protocols/length_protocol.rb +5 -0
  56. data/lib/cosmos/io/json_drb.rb +3 -3
  57. data/lib/cosmos/io/posix_serial_driver.rb +1 -1
  58. data/lib/cosmos/io/win32_serial_driver.rb +23 -2
  59. data/lib/cosmos/packet_logs/packet_log_reader.rb +2 -2
  60. data/lib/cosmos/packets/packet.rb +1 -1
  61. data/lib/cosmos/packets/packet_config.rb +26 -8
  62. data/lib/cosmos/packets/structure.rb +17 -0
  63. data/lib/cosmos/packets/structure_item.rb +5 -1
  64. data/lib/cosmos/packets/telemetry.rb +7 -1
  65. data/lib/cosmos/system/system.rb +115 -48
  66. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +360 -0
  67. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +23 -319
  68. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +14 -17
  69. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +43 -331
  70. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +16 -11
  71. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +1 -0
  72. data/lib/cosmos/tools/config_editor/config_editor.rb +33 -2
  73. data/lib/cosmos/tools/config_editor/config_editor_frame.rb +8 -9
  74. data/lib/cosmos/tools/config_editor/system_config_dialog.rb +158 -0
  75. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +2 -2
  76. data/lib/cosmos/tools/test_runner/test.rb +5 -2
  77. data/lib/cosmos/tools/test_runner/test_runner.rb +2 -2
  78. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +17 -13
  79. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +20 -16
  80. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +18 -11
  81. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +16 -5
  82. data/lib/cosmos/utilities/ruby_lex_utils.rb +34 -30
  83. data/lib/cosmos/version.rb +4 -4
  84. data/lib/cosmos/win32/excel.rb +23 -17
  85. data/run_gui_tests.bat +1 -0
  86. data/spec/core_ext/socket_spec.rb +1 -1
  87. data/spec/install/yaml_docs_spec.rb +26 -6
  88. data/spec/interfaces/protocols/length_protocol_spec.rb +39 -0
  89. data/spec/io/json_drb_spec.rb +14 -0
  90. data/spec/io/win32_serial_driver_spec.rb +16 -2
  91. data/spec/packet_logs/packet_log_reader_spec.rb +2 -2
  92. data/spec/packets/structure_spec.rb +52 -2
  93. data/spec/packets/telemetry_spec.rb +29 -1
  94. data/spec/system/system_spec.rb +2 -2
  95. data/spec/utilities/message_log_spec.rb +6 -3
  96. data/tasks/gemfile_stats.rake +22 -13
  97. metadata +15 -5
  98. data/lib/cosmos/dart/Gemfile +0 -69
@@ -30,7 +30,8 @@ class Dart
30
30
  # streamed from the packet log binary file
31
31
  # 4. Decom Server - JSON DRB server which handles requests for decommutated
32
32
  # or reduced data from the database
33
- # 5..n Worker - Decommutates data from the packet log binary file into the DB
33
+ # 5. Master - Hands out packets to be decommutated by workers
34
+ # 6..n Worker - Decommutates data from the packet log binary file into the DB
34
35
  def run
35
36
  Cosmos::Logger.level = Cosmos::Logger::INFO
36
37
  dart_logging = DartLogging.new('dart')
@@ -53,7 +54,8 @@ class Dart
53
54
  [ruby_process_name, File.join(__dir__, 'dart_ingester.rb')],
54
55
  [ruby_process_name, File.join(__dir__, 'dart_reducer.rb')],
55
56
  [ruby_process_name, File.join(__dir__, 'dart_stream_server.rb')],
56
- [ruby_process_name, File.join(__dir__, 'dart_decom_server.rb')]
57
+ [ruby_process_name, File.join(__dir__, 'dart_decom_server.rb')],
58
+ [ruby_process_name, File.join(__dir__, 'dart_master.rb')]
57
59
  ]
58
60
 
59
61
  num_workers.times do |index|
@@ -26,8 +26,8 @@ Cosmos.catch_fatal_exception do
26
26
  begin
27
27
  json_drb.start_service(Cosmos::System.listen_hosts['DART_DECOM'],
28
28
  Cosmos::System.ports['DART_DECOM'], DartDecomQuery.new)
29
- rescue Exception
30
- raise Cosmos::FatalError.new("Error starting JsonDRb on port #{Cosmos::System.ports['DART_DECOM']}.\nPerhaps another DART Decom Server is already running?")
29
+ rescue Exception => error
30
+ raise Cosmos::FatalError.new("Error starting JsonDRb on port #{Cosmos::System.ports['DART_DECOM']}.\nPerhaps another DART Decom Server is already running?\n#{error.formatted}")
31
31
  end
32
32
  ["TERM", "INT"].each {|sig| Signal.trap(sig) {exit}}
33
33
  Cosmos::Logger.info("Dart Decom Server Started...")
@@ -16,20 +16,57 @@ require 'dart_logging'
16
16
  # Handles packets by writing them to the dart log file. New SYSTEM META packets
17
17
  # cause a new log file to be started.
18
18
  class DartInterfaceThread < Cosmos::InterfaceThread
19
+ include DartCommon
20
+
19
21
  attr_writer :packet_log_writer
20
22
  attr_writer :log_type
21
-
23
+
22
24
  def handle_packet(packet)
23
25
  if packet.target_name == 'SYSTEM'.freeze and packet.packet_name == 'META'.freeze
24
26
  Cosmos::Logger.info("#{@log_type}: #{packet.target_name} #{packet.packet_name}")
27
+
28
+ # Manually read the configuration from the buffer because the packet might not be identified if
29
+ # identify_and_define is false
30
+ buffer = packet.buffer(false)
31
+ if buffer.length >= 33
32
+ system_config_name = Cosmos::BinaryAccessor.read(8, 256, :STRING, buffer, :BIG_ENDIAN)
33
+ # Switch to this system_config
34
+ begin
35
+ switch_and_get_system_config(system_config_name)
36
+ rescue Exception => e
37
+ Cosmos::Logger.error(e.formatted)
38
+ Cosmos::Logger.error("Could not load system_config: #{system_config_name}")
39
+ end
40
+ end
41
+
25
42
  # Update Current Value Table Used By Packet Log Writer
26
43
  cvt_packet = Cosmos::System.telemetry.update!(packet.target_name, packet.packet_name, packet.buffer)
27
44
  cvt_packet.received_time = packet.received_time
28
45
  cvt_packet.stored = packet.stored
29
46
  cvt_packet.extra = packet.extra
47
+
30
48
  @packet_log_writer.start
31
49
  @packet_log_writer.write(cvt_packet)
32
50
  else
51
+ # Define the packet so that packet_time will work correctly
52
+ begin
53
+ packet_data = packet.buffer(false)
54
+ received_time = packet.received_time
55
+ stored = packet.stored
56
+ extra = packet.extra
57
+ if @log_type == :TLM
58
+ packet = Cosmos::System.telemetry.packet(packet.target_name, packet.packet_name)
59
+ else
60
+ packet = Cosmos::System.commands.packet(packet.target_name, packet.packet_name)
61
+ end
62
+ packet.buffer = packet_data
63
+ packet.received_time = received_time
64
+ packet.stored = stored
65
+ packet.extra = extra
66
+ rescue Exception => error
67
+ # Could not find a definition for this packet
68
+ Cosmos::Logger.error "Unknown packet #{target_name} #{packet_name}"
69
+ end
33
70
  @packet_log_writer.write(packet)
34
71
  end
35
72
  end
@@ -0,0 +1,44 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2018 Ball Aerospace & Technologies Corp.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+
11
+ ENV['RAILS_ENV'] = 'production'
12
+ require File.expand_path('../../config/environment', __FILE__)
13
+ require 'dart_common'
14
+ require 'dart_master_query'
15
+
16
+ ples_per_request = ENV['DART_PLE_REQ_SIZE']
17
+ ples_per_request ||= 5
18
+ ples_per_request = ples_per_request.to_i
19
+
20
+ Cosmos.catch_fatal_exception do
21
+ DartCommon.handle_argv
22
+
23
+ Cosmos::Logger.level = Cosmos::Logger::INFO
24
+ dart_logging = DartLogging.new('dart_master')
25
+
26
+ json_drb = Cosmos::JsonDRb.new
27
+ json_drb.acl = Cosmos::System.acl if Cosmos::System.acl
28
+ begin
29
+ json_drb.method_whitelist = ['get_decom_ple_ids']
30
+ begin
31
+ json_drb.start_service(Cosmos::System.listen_hosts['DART_MASTER'],
32
+ Cosmos::System.ports['DART_MASTER'], DartMasterQuery.new(ples_per_request))
33
+ rescue Exception => error
34
+ raise Cosmos::FatalError.new("Error starting JsonDRb on port #{Cosmos::System.ports['DART_MASTER']}.\nPerhaps another DART Master is already running?\n#{error.formatted}")
35
+ end
36
+ ["TERM", "INT"].each {|sig| Signal.trap(sig) {exit}}
37
+ Cosmos::Logger.info("Dart Master Started...")
38
+ sleep(1) while true
39
+ rescue Interrupt
40
+ Cosmos::Logger.info("Dart Master Closing...")
41
+ json_drb.stop_service
42
+ dart_logging.stop
43
+ end
44
+ end
@@ -56,6 +56,8 @@ ENV['RAILS_ENV'] = 'production'
56
56
  require File.expand_path('../../config/environment', __FILE__)
57
57
  require 'dart_database_cleaner'
58
58
 
59
+ include DartCommon
60
+
59
61
  Cosmos.catch_fatal_exception do
60
62
  case action.downcase
61
63
  when 'showpleerrors'
@@ -77,6 +79,119 @@ Cosmos.catch_fatal_exception do
77
79
  Cosmos::Logger.level = Cosmos::Logger::INFO
78
80
  DartDatabaseCleaner.new.remove_packet_log(ARGV[1])
79
81
 
82
+ when 'showdatabase'
83
+ puts "Status:"
84
+ status = Status.last
85
+ puts " Updated At: #{status.updated_at.formatted}"
86
+ puts " Decom Count: #{status.decom_count}"
87
+ puts " Decom Error Count: #{status.decom_error_count}"
88
+ puts " Decom Message: #{status.decom_message}"
89
+ puts " Decom Message Time: #{status.decom_message_time.formatted}"
90
+ puts " Reduction Count: #{status.reduction_count}"
91
+ puts " Reduction Error Count: #{status.reduction_error_count}"
92
+ puts " Reduction Message: #{status.reduction_message}"
93
+ puts " Reduction Message Time: #{status.reduction_message_time}"
94
+ puts ""
95
+
96
+ puts "System Configs:"
97
+ SystemConfig.all.each do |system_config|
98
+ puts " #{sprintf("%6d", system_config.id)} #{system_config.name}"
99
+ end
100
+ puts ""
101
+
102
+ puts "Targets:"
103
+ Target.all.each do |target|
104
+ puts " #{sprintf("%6d", target.id)} #{target.name}"
105
+ end
106
+ puts ""
107
+
108
+ puts "Packets:"
109
+ Packet.all.each do |packet|
110
+ target = Target.find(packet.target_id)
111
+ puts " #{sprintf("%6d", packet.id)} #{target.name} #{packet.name} (#{packet.is_tlm ? "TLM" : "CMD"})"
112
+ end
113
+ puts ""
114
+
115
+ puts "Items:"
116
+ Item.find_each do |item|
117
+ packet = Packet.find(item.packet_id)
118
+ target = Target.find(packet.target_id)
119
+ puts " #{sprintf("%6d", item.id)} #{target.name} #{packet.name} #{item.name}"
120
+ end
121
+ puts ""
122
+
123
+ puts "Packet Logs:"
124
+ PacketLog.all.each do |packet_log|
125
+ puts " #{sprintf("%6d", packet_log.id)} #{packet_log.filename} (#{packet_log.is_tlm ? "TLM" : "CMD"}) #{packet_log.created_at.formatted}"
126
+ end
127
+ puts ""
128
+
129
+ puts "Packet Log Entry Count: #{PacketLogEntry.count}"
130
+ puts ""
131
+
132
+ puts "Packet Configs:"
133
+ PacketConfig.all.each do |packet_config|
134
+ packet = Packet.find(packet_config.packet_id)
135
+ target = Target.find(packet.target_id)
136
+ puts " #{sprintf("%6d", packet_config.id)} #{target.name} #{packet.name} (#{packet_config.name}) sysconfig:#{packet_config.first_system_config_id} maxindex:#{packet_config.max_table_index} ready:#{packet_config.ready} start:#{packet_config.start_time.formatted} end:#{packet_config.end_time.formatted}"
137
+ end
138
+ puts ""
139
+
140
+ value_type_lookup = {0 => "RAW", 1 => "CONVERTED", 2 => "RAW_CON"}
141
+ puts "Item to Decom Table Mappings:"
142
+ ItemToDecomTableMapping.find_each do |itdtm|
143
+ item = Item.find(itdtm.item_id)
144
+ packet = Packet.find(item.packet_id)
145
+ target = Target.find(packet.target_id)
146
+ puts " #{sprintf("%6d", itdtm.id)} #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]} packet_config:#{itdtm.packet_config_id} item_index:#{itdtm.item_index} table_index:#{itdtm.table_index} reduced:#{itdtm.reduced}"
147
+ end
148
+ puts ""
149
+
150
+ puts "Decom and Reduced Tables:"
151
+ each_decom_and_reduced_table do |packet_config_id, table_index, decom_model, minute_model, hour_model, day_model|
152
+ puts " t#{decom_model.name.split("::")[1][1..-1]}: (#{decom_model.count} entries)"
153
+ ItemToDecomTableMapping.where("packet_config_id = ? and table_index = ?", packet_config_id, table_index).order("item_index ASC").each do |itdtm|
154
+ item = Item.find(itdtm.item_id)
155
+ packet = Packet.find(item.packet_id)
156
+ target = Target.find(packet.target_id)
157
+ puts " i#{itdtm.item_index} #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
158
+ end
159
+ puts ""
160
+ puts " t#{minute_model.name.split("::")[1][1..-1]}: (#{minute_model.count} entries)"
161
+ ItemToDecomTableMapping.where("packet_config_id = ? and table_index = ? and reduced = true", packet_config_id, table_index).order("item_index ASC").each do |itdtm|
162
+ item = Item.find(itdtm.item_id)
163
+ packet = Packet.find(item.packet_id)
164
+ target = Target.find(packet.target_id)
165
+ puts " i#{itdtm.item_index}max #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
166
+ puts " i#{itdtm.item_index}min #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
167
+ puts " i#{itdtm.item_index}avg #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
168
+ puts " i#{itdtm.item_index}stddev #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
169
+ end
170
+ puts ""
171
+ puts " t#{hour_model.name.split("::")[1][1..-1]}: (#{hour_model.count} entries)"
172
+ ItemToDecomTableMapping.where("packet_config_id = ? and table_index = ? and reduced = true", packet_config_id, table_index).order("item_index ASC").each do |itdtm|
173
+ item = Item.find(itdtm.item_id)
174
+ packet = Packet.find(item.packet_id)
175
+ target = Target.find(packet.target_id)
176
+ puts " i#{itdtm.item_index}max #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
177
+ puts " i#{itdtm.item_index}min #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
178
+ puts " i#{itdtm.item_index}avg #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
179
+ puts " i#{itdtm.item_index}stddev #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
180
+ end
181
+ puts ""
182
+ puts " t#{day_model.name.split("::")[1][1..-1]}: (#{day_model.count} entries)"
183
+ ItemToDecomTableMapping.where("packet_config_id = ? and table_index = ? and reduced = true", packet_config_id, table_index).order("item_index ASC").each do |itdtm|
184
+ item = Item.find(itdtm.item_id)
185
+ packet = Packet.find(item.packet_id)
186
+ target = Target.find(packet.target_id)
187
+ puts " i#{itdtm.item_index}max #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
188
+ puts " i#{itdtm.item_index}min #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
189
+ puts " i#{itdtm.item_index}avg #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
190
+ puts " i#{itdtm.item_index}stddev #{target.name} #{packet.name} #{item.name} #{value_type_lookup[itdtm.value_type]}"
191
+ end
192
+ puts ""
193
+ end
194
+
80
195
  when 'showpacketlogs'
81
196
  total_size = 0
82
197
  packet_logs = PacketLog.all
@@ -16,6 +16,13 @@ module Cosmos
16
16
  class DartMetaFrame < Qt::Widget
17
17
  @@meta_filters = []
18
18
 
19
+ class LabelPopup < Qt::Label
20
+ attr_accessor :text
21
+ def mousePressEvent(event)
22
+ Qt::MessageBox.critical(self.parent, 'Error', @text)
23
+ end
24
+ end
25
+
19
26
  def initialize(parent)
20
27
  super(parent)
21
28
 
@@ -27,6 +34,7 @@ module Cosmos
27
34
  @groupbox = Qt::GroupBox.new("Meta Filter Selection")
28
35
  @vbox = Qt::VBoxLayout.new(@groupbox)
29
36
  @hbox1 = Qt::HBoxLayout.new
37
+
30
38
  @label = Qt::Label.new("Meta Filters: ")
31
39
  @hbox1.addWidget(@label)
32
40
  @meta_filters_text = Qt::LineEdit.new
@@ -43,6 +51,10 @@ module Cosmos
43
51
  @vbox.addLayout(@hbox1)
44
52
 
45
53
  @hbox2 = Qt::HBoxLayout.new
54
+ @error = LabelPopup.new
55
+ @error.setPixmap(Qt::Application.style.standardIcon(Qt::Style::SP_MessageBoxCritical).pixmap(20, 20))
56
+ @error.hide
57
+ @hbox2.addWidget(@error)
46
58
  @meta_item_name = Qt::ComboBox.new
47
59
  @meta_item_name.setMinimumWidth(200)
48
60
  @meta_item_name.setMaxVisibleItems(6)
@@ -113,8 +125,15 @@ module Cosmos
113
125
  end
114
126
  end
115
127
  @got_meta_item_names = true
116
- rescue Exception
117
- # We tried...
128
+ Qt.execute_in_main_thread { @error.hide }
129
+ rescue Exception => e
130
+ case e.message
131
+ when /execution expired/
132
+ @error.text = "Could not connect to the DART Decom Server. Is it running?"
133
+ else
134
+ @error.text = e.message
135
+ end
136
+ Qt.execute_in_main_thread { @error.show }
118
137
  ensure
119
138
  @update_thread = nil
120
139
  server.disconnect if defined? server
@@ -135,6 +135,11 @@ module Cosmos
135
135
  @length_endianness)
136
136
  raise "Length value received larger than max_length: #{length} > #{@max_length}" if @max_length and length > @max_length
137
137
  packet_length = (length * @length_bytes_per_count) + @length_value_offset
138
+ # Ensure the calculated packet length is long enough to support the location of the length field
139
+ # without overlap into the next packet
140
+ if (packet_length * 8) < (@length_bit_offset + @length_bit_size)
141
+ raise "Calculated packet length of #{packet_length * 8} bits < (offset:#{@length_bit_offset} + size:#{@length_bit_size})"
142
+ end
138
143
 
139
144
  # Make sure we have enough data for the packet
140
145
  return :STOP if @data.length < packet_length
@@ -259,10 +259,10 @@ module Cosmos
259
259
  error_code = nil
260
260
  response_data = nil
261
261
 
262
- if (@method_whitelist and @method_whitelist.include?(request.method)) or
263
- (!@method_whitelist and !JsonRpcRequest::DANGEROUS_METHODS.include?(request.method))
262
+ if (@method_whitelist and @method_whitelist.include?(request.method.downcase())) or
263
+ (!@method_whitelist and !JsonRpcRequest::DANGEROUS_METHODS.include?(request.method.downcase()))
264
264
  begin
265
- result = @object.send(request.method.intern, *request.params)
265
+ result = @object.send(request.method.downcase().intern, *request.params)
266
266
  if request.id
267
267
  response = JsonRpcSuccessResponse.new(result, request.id)
268
268
  end
@@ -59,7 +59,7 @@ module Cosmos
59
59
  cflags |= Termios::CLOCAL # Ignore Modem Control Lines
60
60
  cflags |= Termios::CSTOPB if stop_bits == 2
61
61
  cflags |= Termios::PARENB if parity
62
- cflags |= Termios::PADODD if parity == :ODD
62
+ cflags |= Termios::PARODD if parity == :ODD
63
63
  cflags |= Termios::CRTSCTS if flow_control == :RTSCTS
64
64
  tio.iflag = iflags
65
65
  tio.oflag = 0
@@ -80,8 +80,29 @@ module Cosmos
80
80
  end
81
81
  Win32.set_comm_state(@handle, dcb)
82
82
 
83
- # Configure Timeouts
84
- Win32.set_comm_timeouts(@handle, 4294967295, 0, 0, 0, 0)
83
+ # Configure Timeouts, the WinAPI structure is COMMTIMEOUTS:
84
+ # DWORD ReadIntervalTimeout;
85
+ # DWORD ReadTotalTimeoutMultiplier;
86
+ # DWORD ReadTotalTimeoutConstant;
87
+ # DWORD WriteTotalTimeoutMultiplier;
88
+ # DWORD WriteTotalTimeoutConstant;
89
+ # 0xFFFFFFFF, 0, 0 specifies that the read operation is to return immediately
90
+ # with the bytes that have already been received, even if no bytes have been received.
91
+ # The WriteTotalTimeoutMultiplier is multiplied by the number of bytes to be written
92
+ # and the WriteTotalTimeoutConstant is added to that total (both are in milliseconds).
93
+ bits_per_symbol = data_bits + 1 # 1 start bit
94
+ case stop_bits
95
+ when Win32::ONESTOPBIT
96
+ bits_per_symbol += 1
97
+ when Win32::TWOSTOPBITS
98
+ bits_per_symbol += 2
99
+ end
100
+ case parity
101
+ when Win32::ODDPARITY, Win32::EVENPARITY
102
+ bits_per_symbol += 1
103
+ end
104
+ delay = (1000.0 / (baud_rate / bits_per_symbol.to_f)).ceil
105
+ Win32.set_comm_timeouts(@handle, 0xFFFFFFFF, 0, 0, delay, 1000)
85
106
  end
86
107
 
87
108
  # (see SerialDriver#close)
@@ -152,7 +152,7 @@ module Cosmos
152
152
 
153
153
  # Read Packet Data
154
154
  packet_data = @file.read_length_bytes(4, @max_read_size)
155
- return nil unless packet_data and packet_data.length > 0
155
+ return nil unless packet_data and packet_data.length >= 0
156
156
 
157
157
  if identify_and_define
158
158
  packet = identify_and_define_packet_data(target_name, packet_name, received_time, packet_data)
@@ -275,7 +275,7 @@ module Cosmos
275
275
  end
276
276
  packet.buffer = packet_data
277
277
  packet.set_received_time_fast(received_time)
278
- rescue
278
+ rescue Exception => error
279
279
  # Could not find a definition for this packet
280
280
  Logger.instance.error "Unknown packet #{target_name} #{packet_name}"
281
281
  packet = Packet.new(target_name, packet_name, :BIG_ENDIAN, nil, packet_data)
@@ -341,7 +341,7 @@ module Cosmos
341
341
  previous_item = nil
342
342
  warnings = []
343
343
  @sorted_items.each do |item|
344
- if expected_next_offset and item.bit_offset < expected_next_offset
344
+ if expected_next_offset and (item.bit_offset < expected_next_offset) and !item.overlap
345
345
  msg = "Bit definition overlap at bit offset #{item.bit_offset} for packet #{@target_name} #{@packet_name} items #{item.name} and #{previous_item.name}"
346
346
  Logger.instance.warn(msg)
347
347
  warnings << msg
@@ -198,14 +198,22 @@ module Cosmos
198
198
  #######################################################################
199
199
  # All the following keywords must have a current packet defined
200
200
  #######################################################################
201
- when 'SELECT_ITEM', 'SELECT_PARAMETER', 'ITEM', 'PARAMETER', 'ID_ITEM', 'ID_PARAMETER', 'ARRAY_ITEM', 'ARRAY_PARAMETER', 'APPEND_ITEM', 'APPEND_PARAMETER', 'APPEND_ID_ITEM', 'APPEND_ID_PARAMETER', 'APPEND_ARRAY_ITEM', 'APPEND_ARRAY_PARAMETER', 'MACRO_APPEND_START', 'MACRO_APPEND_END', 'ALLOW_SHORT', 'HAZARDOUS', 'PROCESSOR', 'META', 'DISABLE_MESSAGES', 'HIDDEN', 'DISABLED'
201
+ when 'SELECT_ITEM', 'SELECT_PARAMETER', 'DELETE_ITEM', 'DELETE_PARAMETER', 'ITEM',\
202
+ 'PARAMETER', 'ID_ITEM', 'ID_PARAMETER', 'ARRAY_ITEM', 'ARRAY_PARAMETER', 'APPEND_ITEM',\
203
+ 'APPEND_PARAMETER', 'APPEND_ID_ITEM', 'APPEND_ID_PARAMETER', 'APPEND_ARRAY_ITEM',\
204
+ 'APPEND_ARRAY_PARAMETER', 'MACRO_APPEND_START', 'MACRO_APPEND_END', 'ALLOW_SHORT',\
205
+ 'HAZARDOUS', 'PROCESSOR', 'META', 'DISABLE_MESSAGES', 'HIDDEN', 'DISABLED'
202
206
  raise parser.error("No current packet for #{keyword}") unless @current_packet
203
207
  process_current_packet(parser, keyword, params)
204
208
 
205
209
  #######################################################################
206
210
  # All the following keywords must have a current item defined
207
211
  #######################################################################
208
- when 'STATE', 'READ_CONVERSION', 'WRITE_CONVERSION', 'POLY_READ_CONVERSION', 'POLY_WRITE_CONVERSION', 'SEG_POLY_READ_CONVERSION', 'SEG_POLY_WRITE_CONVERSION', 'GENERIC_READ_CONVERSION_START', 'GENERIC_WRITE_CONVERSION_START', 'REQUIRED', 'LIMITS', 'LIMITS_RESPONSE', 'UNITS', 'FORMAT_STRING', 'DESCRIPTION', 'MINIMUM_VALUE', 'MAXIMUM_VALUE', 'DEFAULT_VALUE', 'OVERFLOW'
212
+ when 'STATE', 'READ_CONVERSION', 'WRITE_CONVERSION', 'POLY_READ_CONVERSION',\
213
+ 'POLY_WRITE_CONVERSION', 'SEG_POLY_READ_CONVERSION', 'SEG_POLY_WRITE_CONVERSION',\
214
+ 'GENERIC_READ_CONVERSION_START', 'GENERIC_WRITE_CONVERSION_START', 'REQUIRED',\
215
+ 'LIMITS', 'LIMITS_RESPONSE', 'UNITS', 'FORMAT_STRING', 'DESCRIPTION',\
216
+ 'MINIMUM_VALUE', 'MAXIMUM_VALUE', 'DEFAULT_VALUE', 'OVERFLOW', 'OVERLAP'
209
217
  raise parser.error("No current item for #{keyword}") unless @current_item
210
218
  process_current_item(parser, keyword, params)
211
219
 
@@ -327,25 +335,31 @@ module Cosmos
327
335
  def process_current_packet(parser, keyword, params)
328
336
  case keyword
329
337
 
330
- # Select an item in the current telemetry packet for editing
331
- when 'SELECT_PARAMETER', 'SELECT_ITEM'
338
+ # Select or delete an item in the current packet
339
+ when 'SELECT_PARAMETER', 'SELECT_ITEM', 'DELETE_PARAMETER', 'DELETE_ITEM'
332
340
  if (@current_cmd_or_tlm == COMMAND) && (keyword.split('_')[1] == 'ITEM')
333
- raise parser.error("SELECT_ITEM only applies to telemetry packets")
341
+ raise parser.error("#{keyword} only applies to telemetry packets")
334
342
  end
335
343
  if (@current_cmd_or_tlm == TELEMETRY) && (keyword.split('_')[1] == 'PARAMETER')
336
- raise parser.error("SELECT_PARAMETER only applies to command packets")
344
+ raise parser.error("#{keyword} only applies to command packets")
337
345
  end
338
346
  usage = "#{keyword} <#{keyword.split('_')[1]} NAME>"
339
347
  finish_item()
340
348
  parser.verify_num_parameters(1, 1, usage)
341
349
  begin
342
- @current_item = @current_packet.get_item(params[0])
350
+ if keyword.include?("SELECT")
351
+ @current_item = @current_packet.get_item(params[0])
352
+ else # DELETE
353
+ @current_packet.delete_item(params[0])
354
+ end
343
355
  rescue # Rescue the default execption to provide a nicer error message
344
356
  raise parser.error("#{params[0]} not found in #{@current_cmd_or_tlm.downcase} packet #{@current_packet.target_name} #{@current_packet.packet_name}", usage)
345
357
  end
346
358
 
347
359
  # Start a new telemetry item in the current packet
348
- when 'ITEM', 'PARAMETER', 'ID_ITEM', 'ID_PARAMETER', 'ARRAY_ITEM', 'ARRAY_PARAMETER', 'APPEND_ITEM', 'APPEND_PARAMETER', 'APPEND_ID_ITEM', 'APPEND_ID_PARAMETER', 'APPEND_ARRAY_ITEM', 'APPEND_ARRAY_PARAMETER'
360
+ when 'ITEM', 'PARAMETER', 'ID_ITEM', 'ID_PARAMETER', 'ARRAY_ITEM', 'ARRAY_PARAMETER',\
361
+ 'APPEND_ITEM', 'APPEND_PARAMETER', 'APPEND_ID_ITEM', 'APPEND_ID_PARAMETER',\
362
+ 'APPEND_ARRAY_ITEM', 'APPEND_ARRAY_PARAMETER'
349
363
  start_item(parser)
350
364
 
351
365
  # Start the creation of a macro-expanded list of items
@@ -570,6 +584,10 @@ module Cosmos
570
584
  parser.verify_num_parameters(1, 1, usage)
571
585
  @current_item.overflow = params[0].to_s.upcase.intern
572
586
 
587
+ when 'OVERLAP'
588
+ parser.verify_num_parameters(0, 0, 'OVERLAP')
589
+ @current_item.overlap = true
590
+
573
591
  end
574
592
  end
575
593