Skip to content

Commit

Permalink
closes #663. Correct use of allow_empty_data and add auto capability
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmelt committed Nov 30, 2017
1 parent 9be4e86 commit dcf5767
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 18 deletions.
5 changes: 4 additions & 1 deletion lib/cosmos/interfaces/protocols/burst_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class BurstProtocol < Protocol
# that will be searched for in the raw data. Bytes encountered before
# this pattern is found are discarded.
# @param fill_fields [Boolean] Fill any required fields when writing packets
def initialize(discard_leading_bytes = 0, sync_pattern = nil, fill_fields = false, allow_empty_data = false)
# @param allow_empty_data [true/false/nil] See Protocol#initialize
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)
Expand All @@ -44,6 +45,8 @@ def reset
#
# @return [String|nil] Data for a packet consisting of the bytes read
def read_data(data)
return super(data) if (data.length <= 0)

@data << data

control = handle_sync_pattern()
Expand Down
5 changes: 4 additions & 1 deletion lib/cosmos/interfaces/protocols/crc_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class CrcProtocol < Protocol

def initialize(write_item_name, strip_crc, bad_strategy, bit_offset,
bit_size = 32, endianness = 'BIG_ENDIAN',
poly = nil, seed = nil, xor = nil, reflect = nil)
poly = nil, seed = nil, xor = nil, reflect = nil, allow_empty_data = nil)
super(allow_empty_data)
@write_item_name = ConfigParser.handle_nil(write_item_name)
@strip_crc = ConfigParser.handle_true_false(strip_crc)
raise "Invalid strip CRC of '#{strip_crc}'. Must be TRUE or FALSE." unless !!@strip_crc == @strip_crc
Expand Down Expand Up @@ -95,6 +96,8 @@ def initialize(write_item_name, strip_crc, bad_strategy, bit_offset,
end

def read_data(data)
return super(data) if (data.length <= 0)

crc = BinaryAccessor.read(@bit_offset, @bit_size, :UINT, data, @endianness)
calculated_crc = @crc.calc(data[0...(@bit_offset / 8)])
if calculated_crc != crc
Expand Down
6 changes: 4 additions & 2 deletions lib/cosmos/interfaces/protocols/fixed_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ class FixedProtocol < BurstProtocol
# telemetry (true) or commands (false)
# @param fill_fields (see BurstProtocol#initialize)
# @param unknown_raise Whether to raise an exception on an unknown packet
# @param allow_empty_data [true/false/nil] See Protocol#initialize
def initialize(
min_id_size,
discard_leading_bytes = 0,
sync_pattern = nil,
telemetry = true,
fill_fields = false,
unknown_raise = false
unknown_raise = false,
allow_empty_data = nil
)
super(discard_leading_bytes, sync_pattern, fill_fields)
super(discard_leading_bytes, sync_pattern, fill_fields, allow_empty_data)
@min_id_size = Integer(min_id_size)
@telemetry = telemetry
@unknown_raise = ConfigParser::handle_true_false(unknown_raise)
Expand Down
6 changes: 4 additions & 2 deletions lib/cosmos/interfaces/protocols/length_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class LengthProtocol < BurstProtocol
# @param max_length [Integer] The maximum allowed value of the length field
# @param fill_length_and_sync_pattern [Boolean] Fill the length field and sync
# pattern when writing packets
# @param allow_empty_data [true/false/nil] See Protocol#initialize
def initialize(
length_bit_offset = 0,
length_bit_size = 16,
Expand All @@ -42,9 +43,10 @@ def initialize(
discard_leading_bytes = 0,
sync_pattern = nil,
max_length = nil,
fill_length_and_sync_pattern = false
fill_length_and_sync_pattern = false,
allow_empty_data = nil
)
super(discard_leading_bytes, sync_pattern, fill_length_and_sync_pattern)
super(discard_leading_bytes, sync_pattern, fill_length_and_sync_pattern, allow_empty_data)

# Save length field attributes
@length_bit_offset = Integer(length_bit_offset)
Expand Down
4 changes: 2 additions & 2 deletions lib/cosmos/interfaces/protocols/override_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ module Cosmos
# methods. Clearing the override requires calling normalize_tlm.
class OverrideProtocol < Protocol

# @param allow_empty_data [true/false] Whether STOP should be returned on empty data
def initialize(allow_empty_data = false)
# @param allow_empty_data [true/false/nil] See Protocol#initialize
def initialize(allow_empty_data = nil)
super(allow_empty_data)
end

Expand Down
5 changes: 3 additions & 2 deletions lib/cosmos/interfaces/protocols/preidentified_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ class PreidentifiedProtocol < BurstProtocol

# @param sync_pattern (see BurstProtocol#initialize)
# @param max_length [Integer] The maximum allowed value of the length field
def initialize(sync_pattern = nil, max_length = nil)
super(0, sync_pattern)
# @param allow_empty_data [true/false/nil] See Protocol#initialize
def initialize(sync_pattern = nil, max_length = 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
Expand Down
20 changes: 16 additions & 4 deletions lib/cosmos/interfaces/protocols/protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ class Protocol
attr_accessor :interface
attr_accessor :allow_empty_data

# @param allow_empty_data [true/false] Whether STOP should be returned on empty data
def initialize(allow_empty_data = false)
# @param allow_empty_data [true/false/nil] Whether or not this protocol will allow an empty string
# to be passed down to later Protocols (instead of returning :STOP). Can be true, false, or nil, where
# nil is interpreted as true unless the Protocol is the last Protocol of the chain.
def initialize(allow_empty_data = nil)
@interface = nil
@allow_empty_data = ConfigParser.handle_true_false(allow_empty_data)
@allow_empty_data = ConfigParser.handle_true_false_nil(allow_empty_data)
reset()
end

Expand All @@ -37,7 +39,17 @@ def disconnect_reset

# Ensure we have some data in case this is the only protocol
def read_data(data)
return :STOP if (data.length <= 0) && !@allow_empty_data
if (data.length <= 0)
if @allow_empty_data.nil?
if @interface and @interface.read_protocols[-1] == self
# Last read interface in chain with auto @allow_empty_data
return :STOP
end
elsif !@allow_empty_data
# Don't @allow_empty_data means STOP
return :STOP
end
end
data
end

Expand Down
9 changes: 7 additions & 2 deletions lib/cosmos/interfaces/protocols/template_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class TemplateProtocol < TerminatedProtocol
# for a response
# @param raise_exceptions [String] Whether to raise exceptions when errors
# occur in the protocol like unexpected responses or response timeouts.
# @param allow_empty_data [true/false/nil] See Protocol#initialize
def initialize(
write_termination_characters,
read_termination_characters,
Expand All @@ -48,15 +49,17 @@ def initialize(
fill_fields = false,
response_timeout = 5.0,
response_polling_period = 0.02,
raise_exceptions = false
raise_exceptions = false,
allow_empty_data = nil
)
super(
write_termination_characters,
read_termination_characters,
strip_read_termination,
discard_leading_bytes,
sync_pattern,
fill_fields)
fill_fields,
allow_empty_data)
@response_template = nil
@response_packet = nil
@response_packets = []
Expand Down Expand Up @@ -93,6 +96,8 @@ def disconnect_reset
end

def read_data(data)
return super(data) if (data.length <= 0)

# Drop all data until the initial_read_delay is complete.
# This gets rid of unused welcome messages,
# prompts, and other junk on initial connections
Expand Down
6 changes: 4 additions & 2 deletions lib/cosmos/interfaces/protocols/terminated_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ class TerminatedProtocol < BurstProtocol
# @param discard_leading_bytes (see BurstProtocol#initialize)
# @param sync_pattern (see BurstProtocol#initialize)
# @param fill_fields (see BurstProtocol#initialize)
# @param allow_empty_data [true/false/nil] See Protocol#initialize
def initialize(
write_termination_characters,
read_termination_characters,
strip_read_termination = true,
discard_leading_bytes = 0,
sync_pattern = nil,
fill_fields = false
fill_fields = false,
allow_empty_data = nil
)
@write_termination_characters = write_termination_characters.hex_to_byte_string
@read_termination_characters = read_termination_characters.hex_to_byte_string
@strip_read_termination = ConfigParser.handle_true_false(strip_read_termination)

super(discard_leading_bytes, sync_pattern, fill_fields)
super(discard_leading_bytes, sync_pattern, fill_fields, allow_empty_data)
end

def write_data(data)
Expand Down
18 changes: 18 additions & 0 deletions spec/interfaces/protocols/burst_protocol_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,24 @@ def read
pkt = @interface.read
expect(pkt.length).to eql 3 # sync plus one byte
end

it "handle auto allow_empty_data correctly" do
@interface.add_protocol(BurstProtocol, [0, nil, false, nil], :READ_WRITE)
expect(@interface.read_protocols[0].read_data("")).to eql :STOP
expect(@interface.read_protocols[0].read_data("A")).to eql "A"
@interface.add_protocol(BurstProtocol, [0, nil, false, nil], :READ_WRITE)
expect(@interface.read_protocols[0].read_data("")).to eql ""
expect(@interface.read_protocols[1].read_data("")).to eql :STOP
expect(@interface.read_protocols[0].read_data("A")).to eql "A"
expect(@interface.read_protocols[1].read_data("A")).to eql "A"
@interface.add_protocol(BurstProtocol, [0, nil, false, nil], :READ_WRITE)
expect(@interface.read_protocols[0].read_data("")).to eql ""
expect(@interface.read_protocols[1].read_data("")).to eql ""
expect(@interface.read_protocols[2].read_data("")).to eql :STOP
expect(@interface.read_protocols[0].read_data("A")).to eql "A"
expect(@interface.read_protocols[1].read_data("A")).to eql "A"
expect(@interface.read_protocols[2].read_data("A")).to eql "A"
end
end

describe "write" do
Expand Down

0 comments on commit dcf5767

Please sign in to comment.