Class: Pio::OpenFlow::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/pio/open_flow/message.rb

Overview

Defines shortcuts to OpenFlow header fields.

Class Method Summary collapse

Class Method Details

._define_initializeObject

rubocop:disable MethodLength rubocop:disable AbcSize



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
# File 'lib/pio/open_flow/message.rb', line 71

def self._define_initialize
  proc do
    def initialize(user_options = {})
      header_options = OpenFlowHeader::Options.parse(user_options)
      body_options = parse_body_options(user_options)
      @format = self.class.format.new(open_flow_header: header_options,
                                      body: body_options)
    end

    private

    def parse_body_options(options)
      if options.respond_to?(:fetch)
        options.delete :transaction_id
        options.delete :xid
        dpid = options[:dpid]
        options[:datapath_id] = dpid if dpid
        if options.keys.size > 1
          options
        else
          options[:user_data] || ''
        end
      else
        ''
      end
    end
  end
end

._define_open_flow_accessorsObject

rubocop:enable MethodLength



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/pio/open_flow/message.rb', line 42

def self._define_open_flow_accessors
  proc do
    def_delegators :@format, :open_flow_header
    def_delegators :open_flow_header, :ofp_version
    def_delegators :open_flow_header, :message_type
    def_delegators :open_flow_header, :message_length
    def_delegators :open_flow_header, :transaction_id
    def_delegator :open_flow_header, :transaction_id, :xid

    def_delegators :@format, :body
    def_delegator :@format, :body, :user_data
  end
end

._define_self_readObject



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/pio/open_flow/message.rb', line 56

def self._define_self_read
  proc do
    def self.read(raw_data)
      allocate.tap do |message|
        message.instance_variable_set(:@format, format.read(raw_data))
      end
    rescue BinData::ValidityError
      message_name = name.split('::')[1..-1].join(' ')
      raise Pio::ParseError, "Invalid #{message_name} message."
    end
  end
end

._define_to_binaryObject

rubocop:enable MethodLength rubocop:enable AbcSize



102
103
104
105
106
# File 'lib/pio/open_flow/message.rb', line 102

def self._define_to_binary
  proc do
    def_delegator :@format, :to_binary_s, :to_binary
  end
end

._format_class(klass, message_type) ⇒ Object

rubocop:disable MethodLength



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/pio/open_flow/message.rb', line 21

def self._format_class(klass, message_type)
  %(
    class Format < BinData::Record
      endian :big

      open_flow_header :open_flow_header,
      message_type_value: #{message_type}
      virtual assert: -> do
        open_flow_header.message_type == #{message_type}
      end

      #{klass.const_defined?(:Body) ? 'body' : 'string'} :body
    end

    def self.format
      const_get :Format
    end
  )
end

.factory(klass, message_type, &block) ⇒ Object



10
11
12
13
14
15
16
17
18
# File 'lib/pio/open_flow/message.rb', line 10

def self.factory(klass, message_type, &block)
  klass.extend Forwardable
  klass.module_eval(&block) if block
  klass.module_eval _format_class(klass, message_type)
  klass.module_eval(&_define_open_flow_accessors)
  klass.module_eval(&_define_self_read)
  klass.module_eval(&_define_initialize)
  klass.module_eval(&_define_to_binary)
end