Class: OpenC3::BurstProtocol
- Defined in:
- lib/openc3/interfaces/protocols/burst_protocol.rb,
ext/openc3/ext/burst_protocol/burst_protocol.c
Overview
Reads all data available on the interface and creates a packet with that data.
Direct Known Subclasses
FixedProtocol, LengthProtocol, PreidentifiedProtocol, TerminatedProtocol
Instance Attribute Summary
Attributes inherited from Protocol
#allow_empty_data, #extra, #interface
Instance Method Summary collapse
-
#handle_sync_pattern ⇒ Boolean
Control code (nil, :STOP).
-
#initialize(discard_leading_bytes = 0, sync_pattern = nil, fill_fields = false, allow_empty_data = nil) ⇒ BurstProtocol
constructor
A new instance of BurstProtocol.
- #log_discard(length, found) ⇒ Object
-
#read_data(*args) ⇒ String|nil
Reads from the interface.
- #reduce_to_single_packet ⇒ Object
- #reset ⇒ Object
-
#write_data(data, extra = nil) ⇒ String
Called to perform modifications on write data before sending it to the interface.
-
#write_packet(packet) ⇒ Packet
Called to perform modifications on a command packet before it is sent.
Methods inherited from Protocol
#connect_reset, #disconnect_reset, #post_write_interface, #protocol_cmd, #read_packet
Constructor Details
#initialize(discard_leading_bytes = 0, sync_pattern = nil, fill_fields = false, allow_empty_data = nil) ⇒ BurstProtocol
Returns a new instance of BurstProtocol.
39 40 41 42 43 44 45 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 39 def initialize(discard_leading_bytes = 0, sync_pattern = nil, fill_fields = false, allow_empty_data = nil) super(allow_empty_data) @discard_leading_bytes = discard_leading_bytes.to_i @sync_pattern = ConfigParser.handle_nil(sync_pattern) @sync_pattern = @sync_pattern.hex_to_byte_string if @sync_pattern @fill_fields = ConfigParser.handle_true_false(fill_fields) end |
Instance Method Details
#handle_sync_pattern ⇒ Boolean
Returns control code (nil, :STOP).
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 114 def handle_sync_pattern if @sync_pattern and @sync_state == :SEARCHING loop do # Make sure we have some data to look for a sync word in return :STOP if @data.length < @sync_pattern.length # Find the beginning of the sync pattern sync_index = @data.index(@sync_pattern.getbyte(0).chr) if sync_index # Make sure we have enough data for the whole sync pattern past this index return :STOP if @data.length < (sync_index + @sync_pattern.length) # Check for the rest of the sync pattern found = true index = sync_index @sync_pattern.each_byte do |byte| if @data.getbyte(index) != byte found = false break end index += 1 end if found if sync_index != 0 log_discard(sync_index, true) # Delete Data Before Sync Pattern @data.replace(@data[sync_index..-1]) end @sync_state = :FOUND return nil else # not found log_discard(sync_index + 1, false) # Delete Data Before and including first character of suspected sync Pattern @data.replace(@data[(sync_index + 1)..-1]) next end # if found else # sync_index = nil log_discard(@data.length, false) @data.replace('') return :STOP end # unless sync_index.nil? end # end loop end # if @sync_pattern nil end |
#log_discard(length, found) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 200 def log_discard(length, found) Logger.error("#{@interface ? @interface.name : ""}: Sync #{'not ' unless found}found. Discarding #{length} bytes of data.") if @data.length >= 0 Logger.error(sprintf("Starting: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", @data.length >= 1 ? @data.getbyte(0) : 0, @data.length >= 2 ? @data.getbyte(1) : 0, @data.length >= 3 ? @data.getbyte(2) : 0, @data.length >= 4 ? @data.getbyte(3) : 0, @data.length >= 5 ? @data.getbyte(4) : 0, @data.length >= 6 ? @data.getbyte(5) : 0)) end end |
#read_data(*args) ⇒ String|nil
Reads from the interface. It can look for a sync pattern before creating a Packet. It can discard a set number of bytes at the beginning before creating the Packet.
Note: On the first call to this from any interface read(), data will contain a blank string. Blank string is an opportunity for protocols to return any queued up packets. If they have no queued up packets, they should pass the blank string down to chained protocols giving them the same opportunity.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 66 def read_data(data, extra = nil) @data << data @extra = extra while true control = handle_sync_pattern() return control if control and data.length > 0 # Only return here if not blank string test # Reduce the data to a single packet packet_data, extra = reduce_to_single_packet() if packet_data == :RESYNC @sync_state = :SEARCHING next if data.length > 0 # Only immediately resync if not blank string test end # Potentially allow blank string to be sent to other protocols if no packet is ready in this one if Symbol === packet_data if (data.length <= 0) and packet_data != :DISCONNECT # On blank string test, return blank string (unless we had a packet or need disconnect) # The base class handles the special case of returning STOP if on the last protocol in the # chain return super(data, extra) else return packet_data, extra # Return any control code if not on blank string test end end @sync_state = :SEARCHING # Discard leading bytes if necessary packet_data.replace(packet_data[@discard_leading_bytes..-1]) if @discard_leading_bytes > 0 return packet_data, extra end end |
#reduce_to_single_packet ⇒ Object
265 266 267 268 269 270 271 272 273 274 275 |
# File 'ext/openc3/ext/burst_protocol/burst_protocol.c', line 265 def reduce_to_single_packet if @data.length <= 0 # Need some data return :STOP end # Reduce to packet data and clear data for next packet packet_data = @data.clone @data.replace('') return packet_data, @extra end |
#reset ⇒ Object
47 48 49 50 51 52 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 47 def reset super() @data = '' @data.force_encoding('ASCII-8BIT') @sync_state = :SEARCHING end |
#write_data(data, extra = nil) ⇒ String
Called to perform modifications on write data before sending it to the interface
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 185 def write_data(data, extra = nil) # If we're filling the sync pattern and discarding the leading bytes # during a read then we need to put them back during a write. # If we're discarding the bytes then by definition they can't be part # of the packet so we just modify the data. if @fill_fields && @discard_leading_bytes > 0 data = ("\x00" * @discard_leading_bytes) << data if @sync_pattern BinaryAccessor.write(@sync_pattern, 0, @sync_pattern.length * 8, :BLOCK, data, :BIG_ENDIAN, :ERROR) end end return super(data, extra) end |
#write_packet(packet) ⇒ Packet
Called to perform modifications on a command packet before it is sent
169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/openc3/interfaces/protocols/burst_protocol.rb', line 169 def write_packet(packet) # If we're filling the sync pattern and the sync pattern is part of the # packet (since we're not discarding any leading bytes) then we have to # fill the sync pattern in the actual packet so do it here. if @fill_fields && @sync_pattern && @discard_leading_bytes == 0 # Directly write the packet buffer and fill in the sync pattern BinaryAccessor.write(@sync_pattern, 0, @sync_pattern.length * 8, :BLOCK, packet.buffer(false), :BIG_ENDIAN, :ERROR) end packet end |