class Ramp::Command

Base class for an AMP protocol command. Any user command should subclassed from this class and define a command name, arguments, reponses and any exceptions or callback method if needed.

Attributes

arguments_hash[RW]
command_name[RW]
responses_hash[RW]
values[R]

Public Class Methods

arguments(args) click to toggle source

Defines all the arguments of the command. arguments should define in a hash and each one value should be a class that have both to_s instance method and to_o class method.

args

is the hash that contains the arguments defination

# File lib/ramp/command.rb, line 45
def arguments args
  @arguments_hash = args
end
command(name) click to toggle source

Define the command name. Remote server will recognize this command this this name.

name

Command name

# File lib/ramp/command.rb, line 37
def command name
  @command_name = name
end
loads(data) click to toggle source

Construct a hash from given data and return it. data should be a packed amp packet.

# File lib/ramp/command.rb, line 59
def loads(data)

  buffer = data.to_s.bytes.to_a
  pos = 0
  result = {}

  while 1 do

    # Parse the next key length
    key_length = 0
    buffer[pos..pos + 1].each {|x| key_length += x}

    if key_length > 255
      raise TypeError, "malform packet."
    end

    if key_length == 0
      # key length of 0 means end of package.
      break
    end

    pos += 2
    # Read the key
    key = buffer[pos..pos + key_length - 1].pack("c*")
  
    # Parse next value length
    pos += key_length
    value_length = 0
    buffer[pos..pos + 1].each {|x| value_length += x}

    # Read the value
    pos += 2
    value = buffer[pos..pos + value_length - 1].pack("c*")
    pos += value_length
    result[key.to_sym] = value

  end

  result
end
new(args) click to toggle source

Inizilize a new command using the args parameter, The args parameter should conatain the exact keys as the hash that specify in arguments

# File lib/ramp/command.rb, line 110
def initialize (args)
  # Initialize an object with provided values for fields defined in
  # @arguments using argument class method
  @values = {}
  @buffer = []
  
  @_args = args

  kwargs = Hash[args.map{|k, v|[k.to_sym, v]}]
  if kwargs.include? :_ask or kwargs.include? :_command
    raise ArgumentError, "':_ask' and ':_command' should not be in arguments"
  end

  kwargs.each do |key, value|

    # Check for key validation
    if not self.class.arguments_hash.include? key
      raise ArgumentError, "'#{key}' is not defined in '#{self.class}'."
    end


    # Construct the values ivar
    @values[key.to_sym] = self.class.arguments_hash[key.to_sym].new value
  end

  # Build a AMP packet data from kwargs hash for more information about
  # amp protocol structure take a look at:
  # http://www.amp-protocol.net
 
  @values[:_command] = self.class.command_name

  while 1 do
    # TODO: is it safe in logic ?
    ask = rand(999999)
    if not @@ask_seqs.include? ask
      @@ask_seqs << ask
      break
    end
  end
  
  @values[:_ask] = ask
  # Generate the packet data and store it into @buffer
  generate_packet
   
end
responses(args) click to toggle source

Defines all the possible responses of the command. Responses should define in a hash and each one value should be a class that have both to_s instance method and to_o class method.

args

is the hash that contains the reponses defination

# File lib/ramp/command.rb, line 53
def responses args
  @responses_hash = args
end

Public Instance Methods

ask() click to toggle source

Return the current command _ask value

# File lib/ramp/command.rb, line 167
def ask
  @values[:_ask]
end
callback(*) click to toggle source

Each subclass may override this method to have a callback when any answer recieved.

# File lib/ramp/command.rb, line 178
def callback (*)
  nil
end
dup() click to toggle source

Duplicat the current command with new _ask value

# File lib/ramp/command.rb, line 172
def dup
  self.class.new @_args
end
to_a() click to toggle source
# File lib/ramp/command.rb, line 162
def to_a
  @buffer
end
to_s() click to toggle source
# File lib/ramp/command.rb, line 157
def to_s
 
  @buffer.pack("c*")      
end

Private Instance Methods

generate_packet() click to toggle source
# File lib/ramp/command.rb, line 193
def generate_packet()
  @values.each do |key, value|

    if key.length > 255
      raise KeyLenError, "AMP keys should have 255 byte max kength"
    end
    
    [0, key.to_s.bytes.to_a.length].each {|x| @buffer << x}
    key.to_s.bytes.to_a.each {|x| @buffer << x}

    value_lenght = split_bytes "%04x" % value.to_s.bytes.to_a.length.to_s(16)
    @buffer << value_lenght[0].to_i
    @buffer << value_lenght[1].to_i
    
    
    value.to_s.bytes.to_a.each {|x| @buffer << x}
  end

  [0x00, 0x00].each {|x| @buffer << x}
end
split_bytes(hex) click to toggle source

Private definations —————————————

# File lib/ramp/command.rb, line 189
def split_bytes (hex)
  hex.each_char.each_slice(2).map {|x| x.join}
end