cosmos 4.2.4-java → 4.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile +1 -1
  4. data/Manifest.txt +12 -0
  5. data/autohotkey/tools/cmd_sequence.ahk +21 -20
  6. data/autohotkey/tools/cmd_sequence2.ahk +1 -1
  7. data/autohotkey/tools/config_editor.ahk +1 -1
  8. data/autohotkey/tools/launcher.ahk +1 -0
  9. data/autohotkey/tools/packet_viewer.ahk +6 -5
  10. data/autohotkey/tools/test_runner.ahk +8 -8
  11. data/bin/cosmos +37 -0
  12. data/bin/dart_util +0 -0
  13. data/data/config/item_modifiers.yaml +9 -0
  14. data/data/crc.txt +91 -86
  15. data/demo/Rakefile +2 -0
  16. data/demo/config/dart/Gemfile +1 -1
  17. data/demo/config/data/crc.txt +8 -5
  18. data/demo/config/system/system.txt +28 -0
  19. data/demo/config/system/system2.txt +21 -3
  20. data/demo/config/system/system_alt_ports.txt +69 -0
  21. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +1 -0
  22. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server_chain.txt +18 -0
  23. data/demo/procedures/cosmos_api_test.rb +18 -14
  24. data/demo/procedures/local_screen_example.rb +51 -0
  25. data/ext/cosmos/ext/cosmos_io/cosmos_io.c +32 -4
  26. data/ext/cosmos/ext/packet/packet.c +6 -0
  27. data/ext/mkrf_conf.rb +2 -2
  28. data/install/config/dart/Gemfile +1 -1
  29. data/install/config/data/crc.txt +2 -2
  30. data/install/config/system/system.txt +23 -1
  31. data/lib/cosmos/conversions.rb +2 -0
  32. data/lib/cosmos/conversions/packet_time_formatted_conversion.rb +38 -0
  33. data/lib/cosmos/conversions/packet_time_seconds_conversion.rb +38 -0
  34. data/lib/cosmos/core_ext/cosmos_io.rb +2 -1
  35. data/lib/cosmos/dart/Gemfile +1 -1
  36. data/lib/cosmos/dart/examples/dart_stream_client.rb +6 -2
  37. data/lib/cosmos/dart/lib/dart_common.rb +1 -1
  38. data/lib/cosmos/dart/lib/dart_database_cleaner.rb +2 -2
  39. data/lib/cosmos/dart/lib/dart_decommutator.rb +4 -4
  40. data/lib/cosmos/dart/lib/dart_importer.rb +3 -3
  41. data/lib/cosmos/dart/lib/dart_packet_log_writer.rb +2 -2
  42. data/lib/cosmos/dart/processes/dart_ingester.rb +2 -0
  43. data/lib/cosmos/dart/processes/dart_util.rb +4 -4
  44. data/lib/cosmos/dart/spec/dart/dart_reducer_manager_spec.rb +3 -3
  45. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +9 -5
  46. data/lib/cosmos/gui/dialogs/details_dialog.rb +29 -29
  47. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +1 -1
  48. data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +3 -3
  49. data/lib/cosmos/gui/dialogs/interface_raw_dialog.rb +2 -2
  50. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +1 -1
  51. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +10 -10
  52. data/lib/cosmos/gui/qt.rb +10 -1
  53. data/lib/cosmos/gui/qt_tool.rb +17 -10
  54. data/lib/cosmos/gui/text/ruby_editor.rb +47 -8
  55. data/lib/cosmos/gui/utilities/classification_banner.rb +60 -0
  56. data/lib/cosmos/gui/utilities/script_module_gui.rb +26 -0
  57. data/lib/cosmos/interfaces.rb +1 -0
  58. data/lib/cosmos/interfaces/interface.rb +4 -0
  59. data/lib/cosmos/interfaces/protocols/ignore_packet_protocol.rb +46 -0
  60. data/lib/cosmos/interfaces/protocols/preidentified_protocol.rb +68 -23
  61. data/lib/cosmos/packet_logs/packet_log_reader.rb +69 -26
  62. data/lib/cosmos/packet_logs/packet_log_writer.rb +13 -1
  63. data/lib/cosmos/packets/commands.rb +5 -1
  64. data/lib/cosmos/packets/packet.rb +36 -2
  65. data/lib/cosmos/packets/packet_config.rb +0 -1
  66. data/lib/cosmos/packets/parsers/format_string_parser.rb +0 -1
  67. data/lib/cosmos/packets/parsers/xtce_parser.rb +1 -1
  68. data/lib/cosmos/packets/telemetry.rb +4 -0
  69. data/lib/cosmos/script/api_shared.rb +2 -0
  70. data/lib/cosmos/script/limits.rb +4 -0
  71. data/lib/cosmos/script/script.rb +27 -11
  72. data/lib/cosmos/script/telemetry.rb +3 -1
  73. data/lib/cosmos/script/tools.rb +18 -8
  74. data/lib/cosmos/system/system.rb +21 -0
  75. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +26 -24
  76. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +29 -29
  77. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +65 -40
  78. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +6 -6
  79. data/lib/cosmos/tools/cmd_tlm_server/api.rb +13 -0
  80. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +12 -9
  81. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +7 -1
  82. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +8 -8
  83. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +13 -2
  84. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +2 -2
  85. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +13 -13
  86. data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +4 -4
  87. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +8 -8
  88. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +5 -5
  89. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +35 -20
  90. data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +15 -11
  91. data/lib/cosmos/tools/config_editor/config_editor.rb +69 -69
  92. data/lib/cosmos/tools/data_viewer/data_viewer.rb +42 -38
  93. data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +1 -0
  94. data/lib/cosmos/tools/data_viewer/dump_component.rb +1 -0
  95. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +4 -4
  96. data/lib/cosmos/tools/launcher/launcher.rb +1 -1
  97. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +28 -24
  98. data/lib/cosmos/tools/opengl_builder/opengl_builder.rb +42 -42
  99. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +56 -53
  100. data/lib/cosmos/tools/script_runner/script_runner.rb +112 -95
  101. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +48 -30
  102. data/lib/cosmos/tools/table_manager/table_manager.rb +42 -42
  103. data/lib/cosmos/tools/test_runner/test_runner.rb +45 -27
  104. data/lib/cosmos/tools/test_runner/test_runner_chooser.rb +3 -3
  105. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +45 -45
  106. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +4 -4
  107. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +3 -3
  108. data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +7 -7
  109. data/lib/cosmos/tools/tlm_grapher/data_object_editors/xy_data_object_editor.rb +10 -10
  110. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +10 -3
  111. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +6 -6
  112. data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +14 -14
  113. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +83 -83
  114. data/lib/cosmos/tools/tlm_viewer/screen.rb +73 -13
  115. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +15 -15
  116. data/lib/cosmos/tools/tlm_viewer/widgets.rb +1 -0
  117. data/lib/cosmos/tools/tlm_viewer/widgets/canvasellipse_widget.rb +40 -0
  118. data/lib/cosmos/tools/tlm_viewer/widgets/timegraph_widget.rb +1 -1
  119. data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +6 -1
  120. data/lib/cosmos/top_level.rb +14 -1
  121. data/lib/cosmos/version.rb +5 -5
  122. data/lib/cosmos/win32/excel.rb +63 -12
  123. data/make_gems.sh +10 -0
  124. data/spec/conversions/packet_time_formatted_conversion_spec.rb +58 -0
  125. data/spec/conversions/packet_time_seconds_conversion_spec.rb +60 -0
  126. data/spec/interfaces/protocols/ignore_packet_protocol_spec.rb +243 -0
  127. data/spec/interfaces/protocols/preidentified_protocol_spec.rb +227 -4
  128. data/spec/io/serial_driver_spec.rb +15 -13
  129. data/spec/packet_logs/packet_log_reader_spec.rb +72 -17
  130. data/spec/packets/packet_config_spec.rb +5 -16
  131. data/spec/packets/parsers/format_string_parser_spec.rb +0 -11
  132. data/spec/packets/parsers/macro_parser_spec.rb +36 -36
  133. data/spec/packets/parsers/state_parser_spec.rb +36 -0
  134. data/spec/packets/telemetry_spec.rb +11 -9
  135. data/spec/script/script_spec.rb +2 -3
  136. data/spec/script/scripting_spec.rb +2 -1
  137. data/spec/script/tools_spec.rb +0 -1
  138. data/spec/tools/cmd_tlm_server/api_spec.rb +28 -20
  139. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +33 -0
  140. data/spec/tools/cmd_tlm_server/commanding_spec.rb +25 -1
  141. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +15 -0
  142. data/tasks/gemfile_stats.rake +3 -2
  143. metadata +14 -2
@@ -0,0 +1,46 @@
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
+ require 'cosmos/config/config_parser'
12
+ require 'cosmos/interfaces/protocols/protocol'
13
+ require 'cosmos/utilities/crc'
14
+ require 'thread'
15
+
16
+ module Cosmos
17
+ # Ignore a specific packet by not letting it through the protocol
18
+ class IgnorePacketProtocol < Protocol
19
+ # @param target_name [String] Target name
20
+ # @param packet_name [String] Packet name
21
+ def initialize(target_name, packet_name, allow_empty_data = nil)
22
+ super(allow_empty_data)
23
+ System.telemetry.packet(target_name, packet_name)
24
+ @target_name = target_name
25
+ @packet_name = packet_name
26
+ end
27
+
28
+ def read_packet(packet)
29
+ # Need to make sure packet is identified and defined
30
+ target_names = nil
31
+ target_names = @interface.target_names if @interface
32
+ identified_packet = System.telemetry.identify_and_define_packet(packet, target_names)
33
+ if identified_packet
34
+ if identified_packet.target_name == @target_name && identified_packet.packet_name == @packet_name
35
+ return :STOP
36
+ end
37
+ end
38
+ return super(packet)
39
+ end
40
+
41
+ def write_packet(packet)
42
+ return :STOP if packet.target_name == @target_name && packet.packet_name == @packet_name
43
+ return super(packet)
44
+ end
45
+ end
46
+ end
@@ -9,6 +9,7 @@
9
9
  # attribution addendums as found in the LICENSE.txt
10
10
 
11
11
  require 'cosmos/interfaces/protocols/burst_protocol'
12
+ require 'cosmos/packet_logs/packet_log_reader'
12
13
 
13
14
  module Cosmos
14
15
  # Delineates packets using the COSMOS preidentification system
@@ -17,10 +18,11 @@ module Cosmos
17
18
  # @param sync_pattern (see BurstProtocol#initialize)
18
19
  # @param max_length [Integer] The maximum allowed value of the length field
19
20
  # @param allow_empty_data [true/false/nil] See Protocol#initialize
20
- def initialize(sync_pattern = nil, max_length = nil, allow_empty_data = nil)
21
+ def initialize(sync_pattern = nil, max_length = nil, mode = 4, allow_empty_data = nil)
21
22
  super(0, sync_pattern, false, allow_empty_data)
22
23
  @max_length = ConfigParser.handle_nil(max_length)
23
24
  @max_length = Integer(@max_length) if @max_length
25
+ @mode = Integer(mode)
24
26
  end
25
27
 
26
28
  def reset
@@ -29,21 +31,34 @@ module Cosmos
29
31
  end
30
32
 
31
33
  def read_packet(packet)
32
- packet.received_time = @received_time
33
- packet.target_name = @target_name
34
- packet.packet_name = @packet_name
34
+ packet.received_time = @read_received_time
35
+ packet.target_name = @read_target_name
36
+ packet.packet_name = @read_packet_name
37
+ if @mode == 4 # COSMOS4.3+ Protocol
38
+ packet.stored = @read_stored
39
+ packet.extra = @read_extra
40
+ end
35
41
  return packet
36
42
  end
37
43
 
38
44
  def write_packet(packet)
39
45
  received_time = packet.received_time
40
46
  received_time = Time.now unless received_time
41
- @time_seconds = [received_time.tv_sec].pack('N') # UINT32
42
- @time_microseconds = [received_time.tv_usec].pack('N') # UINT32
43
- @target_name = packet.target_name
44
- @target_name = 'UNKNOWN' unless @target_name
45
- @packet_name = packet.packet_name
46
- @packet_name = 'UNKNOWN' unless @packet_name
47
+ @write_time_seconds = [received_time.tv_sec].pack('N') # UINT32
48
+ @write_time_microseconds = [received_time.tv_usec].pack('N') # UINT32
49
+ @write_target_name = packet.target_name
50
+ @write_target_name = 'UNKNOWN' unless @write_target_name
51
+ @write_packet_name = packet.packet_name
52
+ @write_packet_name = 'UNKNOWN' unless @write_packet_name
53
+ if @mode == 4 # COSMOS4.3+ Protocol
54
+ @write_flags = 0
55
+ @write_flags |= PacketLogReader::COSMOS4_STORED_FLAG_MASK if packet.stored
56
+ @write_extra = nil
57
+ if packet.extra
58
+ @write_flags |= PacketLogReader::COSMOS4_EXTRA_FLAG_MASK
59
+ @write_extra = packet.extra.to_json
60
+ end
61
+ end
47
62
  return packet
48
63
  end
49
64
 
@@ -51,12 +66,19 @@ module Cosmos
51
66
  data_length = [data.length].pack('N') # UINT32
52
67
  data_to_send = ''
53
68
  data_to_send << @sync_pattern if @sync_pattern
54
- data_to_send << @time_seconds
55
- data_to_send << @time_microseconds
56
- data_to_send << @target_name.length
57
- data_to_send << @target_name
58
- data_to_send << @packet_name.length
59
- data_to_send << @packet_name
69
+ if @mode == 4 # COSMOS4.3+ Protocol
70
+ data_to_send << @write_flags
71
+ if @write_extra
72
+ data_to_send << [@write_extra.length].pack('N')
73
+ data_to_send << @write_extra
74
+ end
75
+ end
76
+ data_to_send << @write_time_seconds
77
+ data_to_send << @write_time_microseconds
78
+ data_to_send << @write_target_name.length
79
+ data_to_send << @write_target_name
80
+ data_to_send << @write_packet_name.length
81
+ data_to_send << @write_packet_name
60
82
  data_to_send << data_length
61
83
  data_to_send << data
62
84
  return data_to_send
@@ -104,27 +126,50 @@ module Cosmos
104
126
  @reduction_state = :SYNC_REMOVED
105
127
  end
106
128
 
107
- # Read and remove packet received time
108
- if @reduction_state == :SYNC_REMOVED
129
+ if @reduction_state == :SYNC_REMOVED and @mode == 4
130
+ # Read and remove flags
131
+ return :STOP if @data.length < 1
132
+ flags = @data[0].unpack('C')[0] # byte
133
+ @data.replace(@data[1..-1])
134
+ @read_stored = false
135
+ @read_stored = true if (flags & PacketLogReader::COSMOS4_STORED_FLAG_MASK) != 0
136
+ @read_extra = nil
137
+ if (flags & PacketLogReader::COSMOS4_EXTRA_FLAG_MASK) != 0
138
+ @reduction_state = :NEED_EXTRA
139
+ else
140
+ @reduction_state = :FLAGS_REMOVED
141
+ end
142
+ end
143
+
144
+ if @reduction_state == :NEED_EXTRA
145
+ # Read and remove extra
146
+ @read_extra = read_length_field_followed_by_string(4)
147
+ return :STOP if @read_extra == :STOP
148
+ @read_extra = JSON.parse(@read_extra)
149
+ @reduction_state = :FLAGS_REMOVED
150
+ end
151
+
152
+ if @reduction_state == :FLAGS_REMOVED or (@reduction_state == :SYNC_REMOVED and @mode != 4)
153
+ # Read and remove packet received time
109
154
  return :STOP if @data.length < 8
110
155
  time_seconds = @data[0..3].unpack('N')[0] # UINT32
111
156
  time_microseconds = @data[4..7].unpack('N')[0] # UINT32
112
- @received_time = Time.at(time_seconds, time_microseconds).sys
157
+ @read_received_time = Time.at(time_seconds, time_microseconds).sys
113
158
  @data.replace(@data[8..-1])
114
159
  @reduction_state = :TIME_REMOVED
115
160
  end
116
161
 
117
162
  if @reduction_state == :TIME_REMOVED
118
163
  # Read and remove the target name
119
- @target_name = read_length_field_followed_by_string(1)
120
- return :STOP if @target_name == :STOP
164
+ @read_target_name = read_length_field_followed_by_string(1)
165
+ return :STOP if @read_target_name == :STOP
121
166
  @reduction_state = :TARGET_NAME_REMOVED
122
167
  end
123
168
 
124
169
  if @reduction_state == :TARGET_NAME_REMOVED
125
170
  # Read and remove the packet name
126
- @packet_name = read_length_field_followed_by_string(1)
127
- return :STOP if @packet_name == :STOP
171
+ @read_packet_name = read_length_field_followed_by_string(1)
172
+ return :STOP if @read_packet_name == :STOP
128
173
  @reduction_state = :PACKET_NAME_REMOVED
129
174
  end
130
175
 
@@ -35,6 +35,18 @@ module Cosmos
35
35
  COSMOS1_LOG_TYPE_RANGE = 6..8
36
36
  COSMOS1_CONFIGURATION_NAME_RANGE = 10..41
37
37
 
38
+ # COSMOS 4.3+ log file header definition
39
+ COSMOS4_MARKER = 'COSMOS4_'
40
+ COSMOS4_HEADER_LENGTH = COSMOS2_HEADER_LENGTH
41
+ COSMOS4_MARKER_RANGE = COSMOS2_MARKER_RANGE
42
+ COSMOS4_LOG_TYPE_RANGE = COSMOS2_LOG_TYPE_RANGE
43
+ COSMOS4_CONFIGURATION_NAME_RANGE = COSMOS2_CONFIGURATION_NAME_RANGE
44
+ COSMOS4_HOSTNAME_RANGE = COSMOS2_HOSTNAME_RANGE
45
+ COSMOS4_STORED_FLAG_MASK = 0x80
46
+ COSMOS4_EXTRA_FLAG_MASK = 0x40
47
+
48
+ MAX_READ_SIZE = 1000000000
49
+
38
50
  # Create a new log file reader
39
51
  def initialize
40
52
  reset()
@@ -62,10 +74,10 @@ module Cosmos
62
74
  packet = read(identify_and_define)
63
75
  break unless packet
64
76
 
65
- received_time = packet.received_time
66
- if received_time
67
- next if start_time and received_time < start_time
68
- break if end_time and received_time > end_time
77
+ time = packet.packet_time
78
+ if time
79
+ next if start_time and time < start_time
80
+ break if end_time and time > end_time
69
81
  end
70
82
 
71
83
  yield packet
@@ -115,6 +127,8 @@ module Cosmos
115
127
  reset()
116
128
  @filename = filename
117
129
  @file = BufferedFile.open(@filename, 'rb')
130
+ @max_read_size = @file.size
131
+ @max_read_size = MAX_READ_SIZE if @max_read_size > MAX_READ_SIZE
118
132
  @bytes_read = 0
119
133
  return read_file_header()
120
134
  rescue => err
@@ -133,11 +147,11 @@ module Cosmos
133
147
  # @return [Packet]
134
148
  def read(identify_and_define = true)
135
149
  # Read the Packet Header
136
- success, target_name, packet_name, received_time = read_entry_header()
150
+ success, target_name, packet_name, received_time, stored, extra = read_entry_header()
137
151
  return nil unless success
138
152
 
139
153
  # Read Packet Data
140
- packet_data = @file.read_length_bytes(4)
154
+ packet_data = @file.read_length_bytes(4, @max_read_size)
141
155
  return nil unless packet_data and packet_data.length > 0
142
156
 
143
157
  if identify_and_define
@@ -147,6 +161,8 @@ module Cosmos
147
161
  packet = Packet.new(target_name, packet_name, :BIG_ENDIAN, nil, packet_data)
148
162
  packet.set_received_time_fast(received_time)
149
163
  end
164
+ packet.stored = stored
165
+ packet.extra = extra
150
166
 
151
167
  # Auto change configuration on SYSTEM META
152
168
  if packet.target_name == 'SYSTEM'.freeze and packet.packet_name == 'META'.freeze
@@ -231,11 +247,13 @@ module Cosmos
231
247
 
232
248
  def reset
233
249
  @file = nil
250
+ @max_read_size = MAX_READ_SIZE
234
251
  @filename = nil
235
252
  @log_type = :TLM
236
253
  @configuration_name = nil
237
254
  @hostname = nil
238
- @file_header_length = COSMOS2_HEADER_LENGTH
255
+ @mode = 4
256
+ @file_header_length = COSMOS4_HEADER_LENGTH
239
257
  end
240
258
 
241
259
  # This is best effort. May return unidentified/undefined packets
@@ -269,10 +287,15 @@ module Cosmos
269
287
 
270
288
  # Should return if successfully switched to requested configuration
271
289
  def read_file_header
272
- header = @file.read(COSMOS2_HEADER_LENGTH)
273
- if header and header.length == COSMOS2_HEADER_LENGTH
274
- if header[COSMOS2_MARKER_RANGE] == COSMOS2_MARKER
275
- # Found COSMOS 2 File Header
290
+ header = @file.read(COSMOS4_HEADER_LENGTH)
291
+ if header and header.length == COSMOS4_HEADER_LENGTH
292
+ if header[COSMOS4_MARKER_RANGE] == COSMOS4_MARKER or header[COSMOS2_MARKER_RANGE] == COSMOS2_MARKER
293
+ # Found COSMOS 2/4 File Header
294
+ if header[COSMOS4_MARKER_RANGE] == COSMOS4_MARKER
295
+ @mode = 4
296
+ else
297
+ @mode = 2
298
+ end
276
299
  @log_type = header[COSMOS2_LOG_TYPE_RANGE].intern
277
300
  raise "Unknown log type #{@log_type}" unless [:CMD, :TLM].include? @log_type
278
301
  @configuration_name = header[COSMOS2_CONFIGURATION_NAME_RANGE]
@@ -283,6 +306,7 @@ module Cosmos
283
306
  return false, error # Did not successfully change to requested configuration name
284
307
  elsif header[COSMOS1_MARKER_RANGE] == COSMOS1_MARKER
285
308
  # Found COSMOS 1 File Header
309
+ @mode = 1
286
310
  @log_type = header[COSMOS1_LOG_TYPE_RANGE].upcase.intern
287
311
  raise "Unknown log type #{@log_type}" unless [:CMD, :TLM].include? @log_type
288
312
  @configuration_name = header[COSMOS1_CONFIGURATION_NAME_RANGE]
@@ -297,29 +321,48 @@ module Cosmos
297
321
  raise "COSMOS file header not found on packet log"
298
322
  end
299
323
  else
300
- raise "Failed to read at least #{COSMOS2_HEADER_LENGTH} bytes from packet log"
324
+ raise "Failed to read at least #{COSMOS4_HEADER_LENGTH} bytes from packet log"
301
325
  end
302
326
  end
303
327
 
304
328
  def read_entry_header
329
+ stored = false
330
+ extra = nil
331
+
332
+ if @mode == 4
333
+ # Read Flags
334
+ flags = @file.read(1)
335
+ return [nil, nil, nil, nil, nil, nil] if flags.nil? or flags.length != 1
336
+ flags = flags.unpack('C')[0]
337
+
338
+ stored = true if (flags & COSMOS4_STORED_FLAG_MASK) != 0
339
+
340
+ if (flags & COSMOS4_EXTRA_FLAG_MASK) != 0
341
+ # Read Extra data
342
+ extra_data = @file.read_length_bytes(4, @max_read_size)
343
+ return [nil, nil, nil, nil, nil, nil] unless extra_data and extra_data.length > 0
344
+ extra = JSON.parse(extra_data)
345
+ end
346
+ end
347
+
305
348
  # Read Received Time
306
349
  time_seconds = @file.read(4)
307
- return [nil, nil, nil, nil] if time_seconds.nil? or time_seconds.length != 4
350
+ return [nil, nil, nil, nil, nil, nil] if time_seconds.nil? or time_seconds.length != 4
308
351
  time_seconds = time_seconds.unpack('N')[0]
309
352
  time_microseconds = @file.read(4)
310
- return [nil, nil, nil, nil] if time_microseconds.nil? or time_microseconds.length != 4
353
+ return [nil, nil, nil, nil, nil, nil] if time_microseconds.nil? or time_microseconds.length != 4
311
354
  time_microseconds = time_microseconds.unpack('N')[0]
312
355
  received_time = Time.at(time_seconds, time_microseconds).sys
313
356
 
314
357
  # Read Target Name
315
358
  target_name = @file.read_length_bytes(1)
316
- return [nil, nil, nil, nil] unless target_name and target_name.length > 0
359
+ return [nil, nil, nil, nil, nil, nil] unless target_name and target_name.length > 0
317
360
 
318
361
  # Read Packet Name
319
362
  packet_name = @file.read_length_bytes(1)
320
- return [nil, nil, nil, nil] unless packet_name and packet_name.length > 0
363
+ return [nil, nil, nil, nil, nil, nil] unless packet_name and packet_name.length > 0
321
364
 
322
- return [true, target_name, packet_name, received_time]
365
+ return [true, target_name, packet_name, received_time, stored, extra]
323
366
  end
324
367
 
325
368
  def test
@@ -331,7 +374,7 @@ module Cosmos
331
374
  begin
332
375
  # Try to read the packet header
333
376
  # This will fail with file read errors and invalid timestamps
334
- success, target_name, packet_name, _ = read_entry_header()
377
+ success, target_name, packet_name, _, _, _ = read_entry_header()
335
378
  if success
336
379
  if target_name !~ File::NON_ASCII_PRINTABLE and packet_name !~ File::NON_ASCII_PRINTABLE
337
380
  packet_data_length = @file.read(4)
@@ -402,17 +445,17 @@ module Cosmos
402
445
  # Read the first packet in the log
403
446
  first_packet = first()
404
447
  raise "Error reading first packet" unless first
405
- raise "First Packet does not contain a packet received time" unless first_packet.received_time
448
+ raise "First Packet does not contain a packet received time" unless first_packet.packet_time
406
449
 
407
450
  # Read the last packet in the log
408
451
  file_size = size()
409
452
  last_packet = last()
410
453
  raise "Search failed looking for last packet" unless last_packet
411
- raise "Last Packet does not contain a packet received time" unless last_packet.received_time
454
+ raise "Last Packet does not contain a packet received time" unless last_packet.packet_time
412
455
 
413
- if time >= first_packet.received_time and time <= last_packet.received_time
456
+ if time >= first_packet.packet_time and time <= last_packet.packet_time
414
457
  # Guess at where to start looking for time in log
415
- percentage = (time - first_packet.received_time) / (last_packet.received_time - first_packet.received_time)
458
+ percentage = (time - first_packet.packet_time) / (last_packet.packet_time - first_packet.packet_time)
416
459
  offset = (percentage * file_size.to_f).to_i
417
460
  offset = @file_header_length if offset < @file_header_length
418
461
  @file.seek(offset, IO::SEEK_SET)
@@ -420,10 +463,10 @@ module Cosmos
420
463
  # Move backwards until a packet before the time is found
421
464
  while true
422
465
  packet = search(-1, :BEFORE)
423
- break if !packet or packet.received_time <= time
466
+ break if !packet or packet.packet_time <= time
424
467
 
425
468
  # Guess again
426
- percentage = 1.0 - ((packet.received_time - time) / (packet.received_time - first_packet.received_time))
469
+ percentage = 1.0 - ((packet.packet_time - time) / (packet.packet_time - first_packet.packet_time))
427
470
  offset = (percentage * @file.pos.to_f).to_i
428
471
  offset = @file_header_length if offset < @file_header_length
429
472
  @file.seek(offset, IO::SEEK_SET)
@@ -434,7 +477,7 @@ module Cosmos
434
477
  position = @file.pos
435
478
  packet = read(false)
436
479
  raise "Search failed looking for packet after time" unless packet
437
- if packet.received_time >= time
480
+ if packet.packet_time >= time
438
481
  # Back up this packet so the read can get it because we want it
439
482
  @file.seek(position, IO::SEEK_SET)
440
483
  break
@@ -442,7 +485,7 @@ module Cosmos
442
485
  end
443
486
 
444
487
  else
445
- if time > last_packet.received_time
488
+ if time > last_packet.packet_time
446
489
  # File is entirely before time, so jump to the end
447
490
  @file.seek(0, IO::SEEK_END)
448
491
  else
@@ -311,7 +311,7 @@ module Cosmos
311
311
 
312
312
  def build_file_header(configuration_name = System.configuration_name)
313
313
  hostname = Socket.gethostname.to_s
314
- file_header = "COSMOS2_#{@log_type}_#{configuration_name.ljust(32, ' ')[0..31]}_"
314
+ file_header = "COSMOS4_#{@log_type}_#{configuration_name.ljust(32, ' ')[0..31]}_"
315
315
  file_header << hostname.ljust(83)
316
316
  return file_header
317
317
  end
@@ -322,6 +322,18 @@ module Cosmos
322
322
  # This is an optimization to avoid creating a new entry_header object
323
323
  # each time we create an entry_header which we do a LOT!
324
324
  @entry_header.clear
325
+ flags = 0
326
+ flags |= PacketLogReader::COSMOS4_STORED_FLAG_MASK if packet.stored
327
+ extra = packet.extra
328
+ if extra
329
+ flags |= PacketLogReader::COSMOS4_EXTRA_FLAG_MASK
330
+ extra = extra.to_json
331
+ end
332
+ @entry_header << [flags].pack('C'.freeze)
333
+ if extra
334
+ @entry_header << [extra.length].pack('N'.freeze)
335
+ @entry_header << extra
336
+ end
325
337
  @entry_header << [received_time.tv_sec].pack('N'.freeze)
326
338
  @entry_header << [received_time.tv_usec].pack('N'.freeze)
327
339
  target_name = packet.target_name
@@ -102,7 +102,9 @@ module Cosmos
102
102
  target_packets.each do |packet_name, packet|
103
103
  if (packet.identify?(packet_data))
104
104
  identified_packet = packet.clone
105
- identified_packet.received_time = nil
105
+ identified_packet.received_time = nil
106
+ identified_packet.stored = false
107
+ identified_packet.extra = nil
106
108
  identified_packet.received_count = 0
107
109
  identified_packet.buffer = packet_data
108
110
  break
@@ -141,6 +143,8 @@ module Cosmos
141
143
 
142
144
  # Set time, parameters, and restore defaults
143
145
  command.received_time = Time.now.sys
146
+ command.stored = false
147
+ command.extra = nil
144
148
  command.given_values = params
145
149
  command.restore_defaults(command.buffer(false), params.keys)
146
150
  command.raw = raw