class SDN::Message
Attributes
ack_requested[RW]
dest[RW]
node_type[RW]
src[RW]
Public Class Methods
expected_response?(message)
click to toggle source
# File lib/sdn/message.rb, line 14 def expected_response?(message) if name =~ /::Get([A-Za-z]+)/ message.class.name == name.sub("::Get", "::Post") else message.is_a?(Ack) || message.is_a?(Nack) end end
inherited(klass)
click to toggle source
# File lib/sdn/message.rb, line 8 def inherited(klass) return Message.inherited(klass) unless self == Message @message_map = nil (@subclasses ||= []) << klass end
new(node_type: nil, ack_requested: false, src: nil, dest: nil)
click to toggle source
# File lib/sdn/message.rb, line 83 def initialize(node_type: nil, ack_requested: false, src: nil, dest: nil) @node_type = node_type || 0 @ack_requested = ack_requested if src.nil? && !dest.nil? && is_group_address?(dest) src = dest dest = nil end @src = src || [0, 0, 1] @dest = dest || [0, 0, 0] end
parse(data)
click to toggle source
# File lib/sdn/message.rb, line 22 def parse(data) offset = -1 msg = length = ack_requested = message_class = nil # we loop here scanning for a valid message loop do offset += 1 # give these weird messages a chance result = ILT2::MasterControl.parse(data) return result if result return [nil, 0] if data.length - offset < 11 msg = to_number(data[offset]) length = to_number(data[offset + 1]) ack_requested = length & 0x80 == 0x80 length &= 0x7f # impossible message next if length < 11 || length > 43 # don't have enough data for what this message wants; # it could be garbage on the line so keep scanning next if length > data.length - offset message_class = message_map[msg] || UnknownMessage calculated_sum = checksum(data.slice(offset, length - 2)) read_sum = data.slice(offset + length - 2, 2) next unless read_sum == calculated_sum break end node_type = node_type_from_number(to_number(data[offset + 2])) src = transform_param(data.slice(offset + 3, 3)) dest = transform_param(data.slice(offset + 6, 3)) begin result = message_class.new(node_type: node_type, ack_requested: ack_requested, src: src, dest: dest) result.parse(data.slice(offset + 9, length - 11)) result.msg = msg if message_class == UnknownMessage rescue ArgumentError => e SDN.logger.warn "discarding illegal message of type #{message_class.name}: #{e}" result = nil end [result, offset + length] end
Private Class Methods
message_map()
click to toggle source
# File lib/sdn/message.rb, line 68 def message_map @message_map ||= @subclasses.inject({}) do |memo, klass| next memo unless klass.constants(false).include?(:MSG) memo[klass.const_get(:MSG, false)] = klass memo end end
Public Instance Methods
==(other)
click to toggle source
# File lib/sdn/message.rb, line 107 def ==(other) self.serialize == other.serialize end
class_inspect()
click to toggle source
# File lib/sdn/message.rb, line 115 def class_inspect ivars = instance_variables - [:@node_type, :@ack_requested, :@src, :@dest, :@params] return if ivars.empty? ivars.map { |iv| ", #{iv}=#{instance_variable_get(iv).inspect}" }.join end
inspect()
click to toggle source
# File lib/sdn/message.rb, line 111 def inspect "#<%s @node_type=%s, @ack_requested=%s, @src=%s, @dest=%s%s>" % [self.class.name, node_type_to_string(node_type), ack_requested, print_address(src), print_address(dest), class_inspect] end
parse(params)
click to toggle source
# File lib/sdn/message.rb, line 94 def parse(params) raise MalformedMessage, "unrecognized params for #{self.class.name}: #{params.map { |b| '%02x' % b }}" if self.class.const_defined?(:PARAMS_LENGTH) && params.length != self.class.const_get(:PARAMS_LENGTH) end
serialize()
click to toggle source
# File lib/sdn/message.rb, line 98 def serialize result = transform_param(node_type_to_number(node_type)) + transform_param(src) + transform_param(dest) + params length = result.length + 4 length |= 0x80 if ack_requested result = transform_param(self.class.const_get(:MSG)) + transform_param(length) + result result.concat(checksum(result)) result.pack("C*") end
Protected Instance Methods
params()
click to toggle source
# File lib/sdn/message.rb, line 123 def params; []; end