Class: OpenC3::PreidentifiedProtocol
- Inherits:
-
BurstProtocol
- Object
- Protocol
- BurstProtocol
- OpenC3::PreidentifiedProtocol
- Defined in:
- lib/openc3/interfaces/protocols/preidentified_protocol.rb
Overview
Delineates packets using the OpenC3 preidentification system
Constant Summary collapse
- COSMOS4_STORED_FLAG_MASK =
0x80- COSMOS4_EXTRA_FLAG_MASK =
0x40
Constants inherited from BurstProtocol
BurstProtocol::DEFAULT_MAX_BUFFER_SIZE
Instance Attribute Summary
Attributes inherited from Protocol
#allow_empty_data, #extra, #interface
Instance Method Summary collapse
-
#initialize(sync_pattern = nil, max_length = nil, _unused = nil, allow_empty_data = nil) ⇒ PreidentifiedProtocol
constructor
A new instance of PreidentifiedProtocol.
- #read_details ⇒ Object
-
#read_length_field_followed_by_string(length_num_bytes) ⇒ Object
protected.
- #read_packet(packet) ⇒ Object
- #reduce_to_single_packet ⇒ Object
- #reset ⇒ Object
- #write_data(data, extra = nil) ⇒ Object
- #write_details ⇒ Object
- #write_packet(packet) ⇒ Object
Methods inherited from BurstProtocol
#check_buffer_size, #handle_sync_pattern, #log_discard, #read_data
Methods inherited from Protocol
#connect_reset, #disconnect_reset, #post_write_interface, #protocol_cmd, #read_data, #read_protocol_input_base, #read_protocol_output_base, #write_protocol_input_base, #write_protocol_output_base
Constructor Details
#initialize(sync_pattern = nil, max_length = nil, _unused = nil, allow_empty_data = nil) ⇒ PreidentifiedProtocol
Returns a new instance of PreidentifiedProtocol.
30 31 32 33 34 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 30 def initialize(sync_pattern = nil, max_length = nil, _unused = nil, allow_empty_data = nil) super(0, sync_pattern, false, allow_empty_data) @max_length = ConfigParser.handle_nil(max_length) @max_length = Integer(@max_length) if @max_length end |
Instance Method Details
#read_details ⇒ Object
215 216 217 218 219 220 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 215 def read_details result = super() result['max_length'] = @max_length result['reduction_state'] = @reduction_state return result end |
#read_length_field_followed_by_string(length_num_bytes) ⇒ Object
protected
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 95 def read_length_field_followed_by_string(length_num_bytes) # Read bytes for string length return :STOP if @data.length < length_num_bytes string_length = @data[0..(length_num_bytes - 1)] case length_num_bytes when 1 string_length = string_length.unpack('C')[0] # UINT8 when 2 string_length = string_length.unpack('n')[0] # UINT16 when 4 string_length = string_length.unpack('N')[0] # UINT32 raise "Length value received larger than max_length: #{string_length} > #{@max_length}" if @max_length and string_length > @max_length # Reject up front rather than buffering the declared number of bytes first if string_length > @max_buffer_size reset() # Drop the partial frame rather than holding it until disconnect raise "Length value received of #{string_length} bytes exceeds maximum buffer size of #{@max_buffer_size} bytes. " \ "Increase OPENC3_PROTOCOL_MAX_BUFFER_SIZE." end else raise "Unsupported length given to read_length_field_followed_by_string: #{length_num_bytes}" end # Read String return :STOP if @data.length < (string_length + length_num_bytes) next_index = string_length + length_num_bytes string = @data[length_num_bytes..(next_index - 1)] # Remove data from current_data @data.replace(@data[next_index..-1]) return string end |
#read_packet(packet) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 41 def read_packet(packet) packet.received_time = @read_received_time packet.target_name = @read_target_name packet.packet_name = @read_packet_name packet.stored = @read_stored if packet.extra and @read_extra packet.extra.merge(@read_extra) else packet.extra = @read_extra end return packet end |
#reduce_to_single_packet ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 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 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 132 def reduce_to_single_packet # Discard sync pattern if present if @sync_pattern if @reduction_state == :START return :STOP if @data.length < @sync_pattern.length @data.replace(@data[(@sync_pattern.length)..-1]) @reduction_state = :SYNC_REMOVED end elsif @reduction_state == :START @reduction_state = :SYNC_REMOVED end if @reduction_state == :SYNC_REMOVED # Read and remove flags return :STOP if @data.length < 1 flags = @data[0].unpack('C')[0] # byte @data.replace(@data[1..-1]) @read_stored = false @read_stored = true if (flags & COSMOS4_STORED_FLAG_MASK) != 0 @read_extra = nil if (flags & COSMOS4_EXTRA_FLAG_MASK) != 0 @reduction_state = :NEED_EXTRA else @reduction_state = :FLAGS_REMOVED end end if @reduction_state == :NEED_EXTRA # Read and remove extra @read_extra = read_length_field_followed_by_string(4) return :STOP if @read_extra == :STOP @read_extra = JSON.parse(@read_extra, allow_nan: true, create_additions: true) @reduction_state = :FLAGS_REMOVED end if @reduction_state == :FLAGS_REMOVED # Read and remove packet received time return :STOP if @data.length < 8 time_seconds = @data[0..3].unpack('N')[0] # UINT32 time_microseconds = @data[4..7].unpack('N')[0] # UINT32 @read_received_time = Time.at(time_seconds, time_microseconds).sys @data.replace(@data[8..-1]) @reduction_state = :TIME_REMOVED end if @reduction_state == :TIME_REMOVED # Read and remove the target name @read_target_name = read_length_field_followed_by_string(1) return :STOP if @read_target_name == :STOP @reduction_state = :TARGET_NAME_REMOVED end if @reduction_state == :TARGET_NAME_REMOVED # Read and remove the packet name @read_packet_name = read_length_field_followed_by_string(1) return :STOP if @read_packet_name == :STOP @reduction_state = :PACKET_NAME_REMOVED end if @reduction_state == :PACKET_NAME_REMOVED # Read packet data and return packet_data = read_length_field_followed_by_string(4) return :STOP if packet_data == :STOP @reduction_state = :START return packet_data, @extra end raise "Error should never reach end of method #{@reduction_state}" end |
#reset ⇒ Object
36 37 38 39 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 36 def reset super() @reduction_state = :START end |
#write_data(data, extra = nil) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 73 def write_data(data, extra = nil) data_length = [data.length].pack('N') # UINT32 data_to_send = '' data_to_send << @sync_pattern if @sync_pattern data_to_send << @write_flags if @write_extra data_to_send << [@write_extra.length].pack('N') data_to_send << @write_extra end data_to_send << @write_time_seconds data_to_send << @write_time_microseconds data_to_send << @write_target_name.length data_to_send << @write_target_name data_to_send << @write_packet_name.length data_to_send << @write_packet_name data_to_send << data_length data_to_send << data return data_to_send, extra end |
#write_details ⇒ Object
209 210 211 212 213 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 209 def write_details result = super() result['max_length'] = @max_length return result end |
#write_packet(packet) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/openc3/interfaces/protocols/preidentified_protocol.rb', line 54 def write_packet(packet) received_time = packet.received_time received_time = Time.now unless received_time @write_time_seconds = [received_time.tv_sec].pack('N') # UINT32 @write_time_microseconds = [received_time.tv_usec].pack('N') # UINT32 @write_target_name = packet.target_name @write_target_name = 'UNKNOWN' unless @write_target_name @write_packet_name = packet.packet_name @write_packet_name = 'UNKNOWN' unless @write_packet_name @write_flags = 0 @write_flags |= COSMOS4_STORED_FLAG_MASK if packet.stored @write_extra = nil if packet.extra @write_flags |= COSMOS4_EXTRA_FLAG_MASK @write_extra = packet.extra.as_json().to_json(allow_nan: true) end return packet end |