Class: Cosmos::PacketLogReader

Inherits:
Object
  • Object
show all
Defined in:
lib/cosmos/packet_logs/packet_log_reader.rb

Overview

Reads a packet log of either commands or telemetry.

Direct Known Subclasses

CcsdsLogReader

Constant Summary collapse

COSMOS2_MARKER =

COSMOS 2.0 log file header definition

'COSMOS2_'
COSMOS2_HEADER_LENGTH =
128
COSMOS2_MARKER_RANGE =
0..7
COSMOS2_LOG_TYPE_RANGE =
8..10
COSMOS2_CONFIGURATION_NAME_RANGE =
12..43
COSMOS2_HOSTNAME_RANGE =
45..127
COSMOS1_MARKER =

COSMOS 1.0 log file header definition

'COSMOS'
COSMOS1_HEADER_LENGTH =
42
COSMOS1_MARKER_RANGE =
0..5
COSMOS1_LOG_TYPE_RANGE =
6..8
COSMOS1_CONFIGURATION_NAME_RANGE =
10..41
COSMOS4_MARKER =

COSMOS 4.3+ log file header definition

'COSMOS4_'
COSMOS4_HEADER_LENGTH =
COSMOS2_HEADER_LENGTH
COSMOS4_MARKER_RANGE =
COSMOS2_MARKER_RANGE
COSMOS4_LOG_TYPE_RANGE =
COSMOS2_LOG_TYPE_RANGE
COSMOS4_CONFIGURATION_NAME_RANGE =
COSMOS2_CONFIGURATION_NAME_RANGE
COSMOS4_HOSTNAME_RANGE =
COSMOS2_HOSTNAME_RANGE
COSMOS4_STORED_FLAG_MASK =
0x80
COSMOS4_EXTRA_FLAG_MASK =
0x40
MAX_READ_SIZE =
1000000000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePacketLogReader

Create a new log file reader



51
52
53
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 51

def initialize
  reset()
end

Instance Attribute Details

#configuration_nameObject (readonly)

Returns the value of attribute configuration_name.



20
21
22
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 20

def configuration_name
  @configuration_name
end

#hostnameObject (readonly)

Returns the value of attribute hostname.



21
22
23
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 21

def hostname
  @hostname
end

#log_typeObject (readonly)

Returns the value of attribute log_type.



19
20
21
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 19

def log_type
  @log_type
end

Instance Method Details

#bytes_readInteger

Returns The current file position in the log file.

Returns:

  • (Integer)

    The current file position in the log file



242
243
244
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 242

def bytes_read
  @file.pos
end

#closeObject

Closes the current log file



140
141
142
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 140

def close
  @file.close if @file and !@file.closed?
end

#each(filename, identify_and_define = true, start_time = nil, end_time = nil) {|packet| ... } ⇒ Object

Yields back each packet as it is found in the log file.

Parameters:

  • filename (String)

    The log file to read

  • identify_and_define (Boolean) (defaults to: true)

    Once the packet has been read from the log file, whether to both identify the packet by setting the target and packet name, and define the packet by populating all the items.

  • start_time (Time|nil) (defaults to: nil)

    Time at which to start returning packets. Packets found with a timestamp before this time are ignored. Pass nil to return all packets.

  • end_time (Time|nil) (defaults to: nil)

    Time at which to stop returning packets. Packets found with a timestamp after this time are ignored. Pass nil to return all packets.

Yield Parameters:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 68

def each(filename, identify_and_define = true, start_time = nil, end_time = nil)
  open(filename)

  seek_to_time(start_time) if start_time

  while true
    packet = read(identify_and_define)
    break unless packet

    time = packet.packet_time
    if time
      next if start_time and time < start_time
      break if end_time and time > end_time
    end

    yield packet
  end
ensure
  close()
end

#firstPacket

Read the first packet from the log file and reset the file position back to the current position. This allows the client to call read multiple times to return packets, call first, and continue calling read which will return the next packet in the file.

Returns:



205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 205

def first
  original_position = @file.pos
  @file.seek(0, IO::SEEK_SET)
  read_file_header()
  packet = read()
  raise "No first packet found" unless packet
  @file.seek(original_position, IO::SEEK_SET)
  packet.clone
rescue => err
  close()
  raise err
end

#lastPacket

Read the last packet from the log file and reset the file position back to the current position. This allows the client to call read multiple times to return packets, call last, and continue calling read which will return the next packet in the file.

Returns:



224
225
226
227
228
229
230
231
232
233
234
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 224

def last
  original_position = @file.pos
  @file.seek(-1, IO::SEEK_END)
  packet = search(-1)
  raise "No last packet found" unless packet
  @file.seek(original_position, IO::SEEK_SET)
  packet.clone
rescue => err
  close()
  raise err
end

#open(filename) ⇒ Boolean, Exception

Returns true if successfully changed to configuration specified in log, otherwise returns false and potentially an Exception class if an error occurred. If no error occurred false indicates that the requested configuration was simply not found

Parameters:

  • filename (String)

    The log filename to open

Returns:

  • (Boolean, Exception)

    Returns true if successfully changed to configuration specified in log, otherwise returns false and potentially an Exception class if an error occurred. If no error occurred false indicates that the requested configuration was simply not found



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 125

def open(filename)
  close()
  reset()
  @filename = filename
  @file = BufferedFile.open(@filename, 'rb')
  @max_read_size = @file.size
  @max_read_size = MAX_READ_SIZE if @max_read_size > MAX_READ_SIZE
  @bytes_read = 0
  return read_file_header()
rescue => err
  close()
  raise err
end

#packet_offsets(filename, progress_callback = nil) ⇒ Array<Array<Integer, Integer, String, String, Time, Time>] Array of arrays for each packet found in the log file consisting of: [File position, length, target name, packet name, time formatted, received time].

Returns an analysis of the log file by reading all the packets and returning information about each packet. This information maps directly to the parameters need by the #read_at_offset method and thus should be called before using #read_at_offset.

Parameters:

  • filename (String)

    The filename to analyze

  • progress_callback (Proc) (defaults to: nil)

    Callback that should receive a single floating point parameter which is the percentage done

Returns:

  • (Array<Array<Integer, Integer, String, String, Time, Time>] Array of arrays for each packet found in the log file consisting of: [File position, length, target name, packet name, time formatted, received time].)

    Array<Array<Integer, Integer, String, String, Time, Time>] Array of arrays for each packet found in the log file consisting of: [File position, length, target name, packet name, time formatted, received time].



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 101

def packet_offsets(filename, progress_callback = nil)
  open(filename)
  offsets = []
  filesize = size().to_f

  while true
    current_pos = @file.pos
    packet = read(false)
    break unless packet
    offsets << current_pos
    if progress_callback
      break if progress_callback.call(current_pos / filesize)
    end
  end

  return offsets
ensure
  close()
end

#read(identify_and_define = true) ⇒ Packet

Read a packet from the log file

Parameters:

  • identify_and_define (Boolean) (defaults to: true)

    Once the packet has been read from the log file, whether to both identify the packet by setting the target and packet name, and define the packet by populating all the items.

Returns:



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 148

def read(identify_and_define = true)
  # Read the Packet Header
  success, target_name, packet_name, received_time, stored, extra = read_entry_header()
  return nil unless success

  # Read Packet Data
  packet_data = @file.read_length_bytes(4, @max_read_size)
  return nil unless packet_data and packet_data.length >= 0

  if identify_and_define
    packet = identify_and_define_packet_data(target_name, packet_name, received_time, packet_data)
  else
    # Build Packet
    packet = Packet.new(target_name, packet_name, :BIG_ENDIAN, nil, packet_data)
    packet.set_received_time_fast(received_time)
  end
  packet.stored = stored
  packet.extra = extra

  # Auto change configuration on SYSTEM META
  if packet.target_name == 'SYSTEM'.freeze and packet.packet_name == 'META'.freeze
    # Manually read the configuration from the buffer because the packet might not be identified if
    # identify_and_define is false
    buffer = packet.buffer(false)
    if buffer.length >= 33
      System.load_configuration(BinaryAccessor.read(8, 256, :STRING, buffer, :BIG_ENDIAN))
    end
  end

  packet.received_count += 1
  packet
rescue => err
  close()
  raise err
end

#read_at_offset(file_offset, identify_and_define = true) ⇒ Packet

Reads a packet from the opened log file. Should only be used in conjunction with #packet_offsets.

Parameters:

  • file_offset (Integer)

    Byte offset into the log file to start reading

  • identify_and_define (Boolean) (defaults to: true)

    Once the packet has been read from the log file, whether to both identify the packet by setting the target and packet name, and define the packet by populating all the items.

Returns:



191
192
193
194
195
196
197
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 191

def read_at_offset(file_offset, identify_and_define = true)
  @file.seek(file_offset, IO::SEEK_SET)
  return read(identify_and_define)
rescue => err
  close()
  raise err
end

#sizeInteger

Returns The size of the log file being processed.

Returns:

  • (Integer)

    The size of the log file being processed



237
238
239
# File 'lib/cosmos/packet_logs/packet_log_reader.rb', line 237

def size
  @file.stat.size
end