pio 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -1
  3. data/README.md +24 -11
  4. data/Rakefile +0 -2
  5. data/examples/features_new.rb +17 -6
  6. data/features/packet_data/aggregate_stats_reply.raw +0 -0
  7. data/features/packet_data/aggregate_stats_request.raw +0 -0
  8. data/features/packet_data/barrier_reply.raw +0 -0
  9. data/features/packet_data/barrier_request.raw +0 -0
  10. data/features/packet_data/desc_stats_reply.raw +0 -0
  11. data/features/packet_data/desc_stats_request.raw +0 -0
  12. data/features/packet_data/echo_reply.raw +0 -0
  13. data/features/packet_data/echo_request.raw +0 -0
  14. data/features/packet_data/error.raw +0 -0
  15. data/features/packet_data/features_reply.raw +0 -0
  16. data/features/packet_data/flow_mod_add.raw +0 -0
  17. data/features/packet_data/flow_mod_delete.raw +0 -0
  18. data/features/packet_data/flow_removed.raw +0 -0
  19. data/features/packet_data/flow_stats_reply.raw +0 -0
  20. data/features/packet_data/flow_stats_request.raw +0 -0
  21. data/features/packet_data/get_config_reply.raw +0 -0
  22. data/features/packet_data/get_config_request.raw +0 -0
  23. data/features/packet_data/hello.raw +0 -0
  24. data/features/packet_data/packet_in.raw +0 -0
  25. data/features/packet_data/packet_out.raw +0 -0
  26. data/features/packet_data/port_mod.raw +0 -0
  27. data/features/packet_data/port_stats_reply.raw +0 -0
  28. data/features/packet_data/port_stats_request.raw +0 -0
  29. data/features/packet_data/port_status.raw +0 -0
  30. data/features/packet_data/queue_get_config_reply.raw +0 -0
  31. data/features/packet_data/queue_get_config_request.raw +0 -0
  32. data/features/packet_data/set_config.raw +0 -0
  33. data/features/packet_data/table_stats_reply.raw +0 -0
  34. data/features/packet_data/table_stats_request.raw +0 -0
  35. data/features/packet_data/vendor.raw +0 -0
  36. data/features/packet_data/vendor_stats_request.raw +0 -0
  37. data/features/step_definitions/packet_data_steps.rb +0 -2
  38. data/features/step_definitions/pending_steps.rb +0 -2
  39. data/features/support/env.rb +0 -2
  40. data/lib/pio.rb +0 -2
  41. data/lib/pio/arp.rb +0 -2
  42. data/lib/pio/arp/format.rb +0 -2
  43. data/lib/pio/arp/message.rb +14 -22
  44. data/lib/pio/arp/reply.rb +0 -2
  45. data/lib/pio/arp/request.rb +0 -2
  46. data/lib/pio/dhcp.rb +0 -2
  47. data/lib/pio/dhcp/ack.rb +0 -2
  48. data/lib/pio/dhcp/boot_reply.rb +0 -2
  49. data/lib/pio/dhcp/boot_reply_options.rb +0 -2
  50. data/lib/pio/dhcp/boot_request.rb +0 -2
  51. data/lib/pio/dhcp/boot_request_options.rb +0 -2
  52. data/lib/pio/dhcp/client_id.rb +0 -2
  53. data/lib/pio/dhcp/common_options.rb +0 -2
  54. data/lib/pio/dhcp/csum_util.rb +0 -2
  55. data/lib/pio/dhcp/dhcp_field.rb +0 -2
  56. data/lib/pio/dhcp/dhcp_tlv_options.rb +0 -2
  57. data/lib/pio/dhcp/discover.rb +0 -2
  58. data/lib/pio/dhcp/field_util.rb +0 -2
  59. data/lib/pio/dhcp/frame.rb +0 -2
  60. data/lib/pio/dhcp/message.rb +0 -2
  61. data/lib/pio/dhcp/offer.rb +0 -2
  62. data/lib/pio/dhcp/optional_tlv.rb +0 -2
  63. data/lib/pio/dhcp/parameter_list.rb +0 -2
  64. data/lib/pio/dhcp/request.rb +0 -2
  65. data/lib/pio/echo.rb +3 -6
  66. data/lib/pio/echo/format.rb +10 -6
  67. data/lib/pio/echo/message.rb +16 -41
  68. data/lib/pio/echo/reply.rb +8 -7
  69. data/lib/pio/echo/request.rb +6 -6
  70. data/lib/pio/features.rb +15 -9
  71. data/lib/pio/features/reply.rb +79 -44
  72. data/lib/pio/features/request.rb +30 -28
  73. data/lib/pio/hello.rb +17 -29
  74. data/lib/pio/hello/format.rb +8 -8
  75. data/lib/pio/icmp.rb +0 -2
  76. data/lib/pio/icmp/format.rb +0 -2
  77. data/lib/pio/icmp/message.rb +23 -31
  78. data/lib/pio/icmp/options.rb +0 -2
  79. data/lib/pio/icmp/reply.rb +2 -4
  80. data/lib/pio/icmp/request.rb +0 -2
  81. data/lib/pio/ipv4_address.rb +1 -5
  82. data/lib/pio/lldp.rb +0 -2
  83. data/lib/pio/lldp/chassis_id_tlv.rb +0 -2
  84. data/lib/pio/lldp/end_of_lldpdu_value.rb +0 -2
  85. data/lib/pio/lldp/frame.rb +0 -2
  86. data/lib/pio/lldp/management_address_value.rb +0 -2
  87. data/lib/pio/lldp/optional_tlv.rb +0 -2
  88. data/lib/pio/lldp/options.rb +0 -2
  89. data/lib/pio/lldp/organizationally_specific_value.rb +0 -2
  90. data/lib/pio/lldp/port_description_value.rb +0 -2
  91. data/lib/pio/lldp/port_id_tlv.rb +0 -2
  92. data/lib/pio/lldp/system_capabilities_value.rb +0 -2
  93. data/lib/pio/lldp/system_description_value.rb +0 -2
  94. data/lib/pio/lldp/system_name_value.rb +0 -2
  95. data/lib/pio/lldp/ttl_tlv.rb +0 -2
  96. data/lib/pio/mac.rb +2 -6
  97. data/lib/pio/message_type_selector.rb +5 -4
  98. data/lib/pio/open_flow.rb +5 -0
  99. data/lib/pio/open_flow/flags.rb +38 -0
  100. data/lib/pio/open_flow/message.rb +20 -0
  101. data/lib/pio/open_flow/open_flow_header.rb +18 -0
  102. data/lib/pio/open_flow/phy_port.rb +74 -0
  103. data/lib/pio/open_flow/type.rb +12 -0
  104. data/lib/pio/options.rb +0 -2
  105. data/lib/pio/parse_error.rb +0 -2
  106. data/lib/pio/pcap.rb +0 -2
  107. data/lib/pio/type/ethernet_header.rb +0 -2
  108. data/lib/pio/type/ip_address.rb +0 -2
  109. data/lib/pio/type/ipv4_header.rb +2 -2
  110. data/lib/pio/type/mac_address.rb +6 -3
  111. data/lib/pio/type/udp_header.rb +0 -2
  112. data/lib/pio/version.rb +1 -3
  113. data/pio.gemspec +18 -20
  114. data/spec/pio/arp/reply/options_spec.rb +0 -2
  115. data/spec/pio/arp/reply_spec.rb +0 -2
  116. data/spec/pio/arp/request/options_spec.rb +0 -2
  117. data/spec/pio/arp/request_spec.rb +0 -2
  118. data/spec/pio/arp_spec.rb +0 -2
  119. data/spec/pio/dhcp/ack_spec.rb +0 -2
  120. data/spec/pio/dhcp/discover_spec.rb +0 -2
  121. data/spec/pio/dhcp/offer_spec.rb +0 -2
  122. data/spec/pio/dhcp/request_spec.rb +0 -2
  123. data/spec/pio/dhcp_spec.rb +0 -2
  124. data/spec/pio/echo/reply_spec.rb +13 -15
  125. data/spec/pio/echo/request_spec.rb +15 -15
  126. data/spec/pio/echo_spec.rb +5 -7
  127. data/spec/pio/features/reply_spec.rb +47 -17
  128. data/spec/pio/features/request_spec.rb +6 -11
  129. data/spec/pio/features_spec.rb +70 -51
  130. data/spec/pio/hello_spec.rb +1 -3
  131. data/spec/pio/icmp/reply_spec.rb +0 -2
  132. data/spec/pio/icmp/request_spec.rb +0 -2
  133. data/spec/pio/icmp_spec.rb +0 -2
  134. data/spec/pio/ipv4_address_spec.rb +0 -2
  135. data/spec/pio/lldp/options_spec.rb +0 -2
  136. data/spec/pio/lldp_spec.rb +0 -2
  137. data/spec/pio/mac_spec.rb +0 -1
  138. data/spec/pio/open_flow/phy_port_spec.rb +25 -0
  139. data/spec/pio/open_flow/type_spec.rb +5 -0
  140. data/spec/spec_helper.rb +9 -24
  141. metadata +105 -40
  142. data/lib/pio/features/format.rb +0 -18
  143. data/lib/pio/features/message.rb +0 -14
  144. data/lib/pio/type/open_flow.rb +0 -34
@@ -1,48 +1,23 @@
1
- # encoding: utf-8
2
-
3
- require 'forwardable'
4
- require 'bindata'
5
-
6
1
  module Pio
7
2
  class Echo
8
3
  # Base class of Echo request and reply.
9
- class Message
10
- extend Forwardable
11
-
12
- def_delegators :@echo, :ofp_version
13
- def_delegators :@echo, :message_type
14
- def_delegators :@echo, :message_length
15
- def_delegators :@echo, :transaction_id
16
- def_delegator :@echo, :transaction_id, :xid
17
- def_delegator :@echo, :body, :data
18
- def_delegator :@echo, :to_binary_s, :to_binary
19
-
20
- def self.create_from(echo)
21
- message = allocate
22
- message.instance_variable_set :@echo, echo
23
- message
24
- end
25
-
26
- def initialize(message_type, user_options = {})
27
- if user_options.respond_to?(:to_i)
28
- @options = { transaction_id: user_options.to_i,
29
- message_type: message_type }
30
- elsif user_options.respond_to?(:[])
31
- @options = user_options.dup.merge(message_type: message_type)
32
- handle_user_hash_options
33
- else
34
- fail TypeError
35
- end
36
- @echo = Format.new(@options)
37
- end
38
-
39
- private
40
-
41
- def handle_user_hash_options
42
- @options[:body] = @options[:data]
43
- @options[:transaction_id] ||= @options[:xid]
44
- @options[:transaction_id] = 0 unless @options[:transaction_id]
4
+ class Message < Pio::OpenFlow::Message
5
+ # @reek This method smells of :reek:FeatureEnvy
6
+ # rubocop:disable Metrics/MethodLength
7
+ def initialize(user_options = {})
8
+ options = if user_options.respond_to?(:to_i)
9
+ { open_flow_header: { transaction_id: user_options.to_i } }
10
+ elsif user_options.respond_to?(:fetch)
11
+ transaction_id =
12
+ user_options[:transaction_id] || user_options[:xid] || 0
13
+ { open_flow_header: { transaction_id: transaction_id },
14
+ body: user_options[:user_data] }
15
+ else
16
+ fail TypeError
17
+ end
18
+ @format = self.class.const_get(:Format).new(options)
45
19
  end
20
+ # rubocop:enable Metrics/MethodLength
46
21
  end
47
22
  end
48
23
  end
@@ -1,13 +1,17 @@
1
- # encoding: utf-8
2
-
1
+ require 'forwardable'
3
2
  require 'pio/echo/format'
4
3
  require 'pio/echo/message'
4
+ require 'pio/open_flow'
5
5
 
6
6
  module Pio
7
- # OpenFlow Echo Request and Reply message parser.
8
7
  class Echo
9
- # OpenFlow 1.0 Echo Reply message.
8
+ # OpenFlow 1.0 Echo Reply message generator.
10
9
  class Reply < Message
10
+ # OpenFlow 1.0 Echo reply message generator.
11
+ class Format < Pio::Echo::Format
12
+ default_parameters message_type_value: Pio::OpenFlow::Type::ECHO_REPLY
13
+ end
14
+
11
15
  # Creates an EchoReply OpenFlow message. This message can be
12
16
  # used to measure the bandwidth of a controller/switch
13
17
  # connection as well as to verify its liveness.
@@ -37,9 +41,6 @@ module Pio
37
41
  # timestamp to check latency, various lengths to measure
38
42
  # bandwidth or zero-size(nil) to verify liveness between the
39
43
  # switch and controller.
40
- def initialize(user_options = {})
41
- super REPLY, user_options
42
- end
43
44
  end
44
45
  end
45
46
  end
@@ -1,13 +1,16 @@
1
- # encoding: utf-8
2
-
3
1
  require 'pio/echo/format'
4
2
  require 'pio/echo/message'
3
+ require 'pio/open_flow'
5
4
 
6
5
  module Pio
7
- # OpenFlow Echo Request and Reply message parser.
8
6
  class Echo
9
7
  # OpenFlow 1.0 Echo Request message.
10
8
  class Request < Message
9
+ # OpenFlow 1.0 Echo request message generator.
10
+ class Format < Pio::Echo::Format
11
+ default_parameters message_type_value: Pio::OpenFlow::Type::ECHO_REQUEST
12
+ end
13
+
11
14
  # Creates an EchoRequest OpenFlow message. This message can be
12
15
  # used to measure the bandwidth of a controller/switch
13
16
  # connection as well as to verify its liveness.
@@ -37,9 +40,6 @@ module Pio
37
40
  # timestamp to check latency, various lengths to measure
38
41
  # bandwidth or zero-size(nil) to verify liveness between the
39
42
  # switch and controller.
40
- def initialize(user_options = {})
41
- super REQUEST, user_options
42
- end
43
43
  end
44
44
  end
45
45
  end
@@ -1,18 +1,24 @@
1
- # encoding: utf-8
2
-
3
- require 'pio/features/format'
4
1
  require 'pio/features/reply'
5
2
  require 'pio/features/request'
6
- require 'pio/message_type_selector'
3
+ require 'pio/open_flow'
4
+ require 'pio/parse_error'
7
5
 
8
6
  module Pio
9
7
  # OpenFlow 1.0 Features messages
10
8
  class Features
11
- extend MessageTypeSelector
12
-
13
- REQUEST = 5
14
- REPLY = 6
9
+ include Pio::OpenFlow::Type
15
10
 
16
- message_type REQUEST => Request, REPLY => Reply
11
+ # @reek This method smells of :reek:TooManyStatements
12
+ def self.read(raw_data)
13
+ header = Pio::Type::OpenFlow::OpenFlowHeader.read(raw_data)
14
+ klass = { FEATURES_REQUEST => Request,
15
+ FEATURES_REPLY => Reply }.fetch(header.message_type)
16
+ format = klass.const_get(:Format).read(raw_data)
17
+ message = klass.allocate
18
+ message.instance_variable_set :@format, format
19
+ message
20
+ rescue KeyError
21
+ raise Pio::ParseError, 'Invalid features request/reply message.'
22
+ end
17
23
  end
18
24
  end
@@ -1,15 +1,50 @@
1
- # encoding: utf-8
2
-
3
1
  require 'bindata'
4
- require 'forwardable'
5
- require 'pio/features/message'
2
+ require 'pio/open_flow'
6
3
 
7
4
  module Pio
8
5
  # OpenFlow 1.0 Features messages
9
6
  class Features
10
7
  # OpenFlow 1.0 Features Reply message
11
- class Reply < Message
12
- # Message body of Features Reply
8
+ class Reply < Pio::OpenFlow::Message
9
+ # enum ofp_capabilities
10
+ class Capabilities < BinData::Primitive
11
+ extend Flags
12
+
13
+ endian :big
14
+
15
+ flags :capabilities,
16
+ flow_stats: 1 << 0,
17
+ table_stats: 1 << 1,
18
+ port_stats: 1 << 2,
19
+ stp: 1 << 3,
20
+ reserved: 1 << 4,
21
+ ip_reasm: 1 << 5,
22
+ queue_stats: 1 << 6,
23
+ arp_match_ip: 1 << 7
24
+ end
25
+
26
+ # enum ofp_action_type
27
+ class Actions < BinData::Primitive
28
+ extend Flags
29
+
30
+ endian :big
31
+
32
+ flags :actions,
33
+ output: 1 << 0,
34
+ set_vlan_vid: 1 << 1,
35
+ set_vlan_pcp: 1 << 2,
36
+ strip_vlan: 1 << 3,
37
+ set_dl_src: 1 << 4,
38
+ set_dl_dst: 1 << 5,
39
+ set_nw_src: 1 << 6,
40
+ set_nw_dst: 1 << 7,
41
+ set_nw_tos: 1 << 8,
42
+ set_tp_src: 1 << 9,
43
+ set_tp_dst: 1 << 10,
44
+ enqueue: 1 << 11
45
+ end
46
+
47
+ # Message body of features reply.
13
48
  class Body < BinData::Record
14
49
  endian :big
15
50
 
@@ -17,56 +52,56 @@ module Pio
17
52
  uint32 :n_buffers
18
53
  uint8 :n_tables
19
54
  uint24 :padding
20
- uint32 :capabilities
21
- uint32 :actions
55
+ hide :padding
56
+ capabilities :capabilities
57
+ actions :actions
22
58
  array :ports, type: :phy_port, read_until: :eof
23
- end
24
-
25
- extend Forwardable
26
59
 
27
- def_delegators :@features, :ofp_version
28
- def_delegators :@features, :message_type
29
- def_delegators :@features, :message_length
30
- def_delegators :@features, :transaction_id
31
- def_delegator :@features, :transaction_id, :xid
32
- def_delegators :@features, :body
60
+ def empty?
61
+ false
62
+ end
33
63
 
34
- def initialize(user_options = {})
35
- @options = user_options.dup.merge(datapath_id: user_options[:dpid])
36
- body = Body.new(@options)
37
- @features = Format.new(@options.merge(message_type: 6,
38
- body: body.to_binary_s))
64
+ def length
65
+ 24 + ports.to_binary_s.length
66
+ end
39
67
  end
40
68
 
41
- def datapath_id
42
- @body ||= Body.read(@features.body)
43
- @body.datapath_id
44
- end
45
- alias_method :dpid, :datapath_id
69
+ # OpenFlow 1.0 Features request message.
70
+ class Format < BinData::Record
71
+ include Pio::OpenFlow::Type
46
72
 
47
- def n_buffers
48
- @body ||= Body.read(@features.body)
49
- @body.n_buffers
50
- end
73
+ endian :big
51
74
 
52
- def n_tables
53
- @body ||= Body.read(@features.body)
54
- @body.n_tables
55
- end
75
+ open_flow_header :open_flow_header, message_type_value: FEATURES_REPLY
76
+ virtual assert: -> { open_flow_header.message_type == FEATURES_REPLY }
56
77
 
57
- def capabilities
58
- @body ||= Body.read(@features.body)
59
- @body.capabilities
78
+ body :body
60
79
  end
61
80
 
62
- def actions
63
- @body ||= Body.read(@features.body)
64
- @body.actions
81
+ def datapath_id
82
+ @format.body.datapath_id
65
83
  end
66
84
 
67
- def ports
68
- @body ||= Body.read(@features.body)
69
- @body.ports
85
+ def_delegators :body, :datapath_id
86
+ def_delegator :body, :datapath_id, :dpid
87
+ def_delegators :body, :n_buffers
88
+ def_delegators :body, :n_tables
89
+ def_delegators :body, :capabilities
90
+ def_delegators :body, :actions
91
+ def_delegators :body, :ports
92
+
93
+ # @reek This method smells of :reek:FeatureEnvy
94
+ def initialize(user_options)
95
+ body_options =
96
+ {
97
+ datapath_id: user_options[:dpid],
98
+ n_buffers: user_options[:n_buffers],
99
+ n_tables: user_options[:n_tables],
100
+ capabilities: user_options[:capabilities],
101
+ actions: user_options[:actions],
102
+ ports: user_options[:ports]
103
+ }
104
+ @format = Format.new(user_options.merge(body: body_options))
70
105
  end
71
106
  end
72
107
  end
@@ -1,22 +1,24 @@
1
- # encoding: utf-8
2
-
3
1
  require 'forwardable'
4
- require 'pio/features/message'
2
+ require 'pio/open_flow'
5
3
 
6
4
  module Pio
7
5
  # OpenFlow 1.0 Features messages
8
6
  class Features
9
7
  # OpenFlow 1.0 Features Request message
10
- class Request < Message
11
- extend Forwardable
8
+ class Request < Pio::OpenFlow::Message
9
+ # OpenFlow 1.0 Features Request format
10
+ class Format < BinData::Record
11
+ include Pio::OpenFlow::Type
12
+
13
+ endian :big
14
+
15
+ open_flow_header :open_flow_header, message_type_value: FEATURES_REQUEST
16
+ virtual assert: -> { open_flow_header.message_type == FEATURES_REQUEST }
12
17
 
13
- def_delegators :@features, :ofp_version
14
- def_delegators :@features, :message_type
15
- def_delegators :@features, :message_length
16
- def_delegators :@features, :transaction_id
17
- def_delegator :@features, :transaction_id, :xid
18
- def_delegators :@features, :body
19
- def_delegator :@features, :to_binary_s, :to_binary
18
+ def body
19
+ ''
20
+ end
21
+ end
20
22
 
21
23
  # Creates a Features Request OpenFlow message.
22
24
  #
@@ -39,25 +41,25 @@ module Pio
39
41
  # The options to create a message with.
40
42
  # @option user_options [Number] :transaction_id
41
43
  # @option user_options [Number] :xid An alias to transaction_id.
44
+ #
45
+ # @reek This method smells of :reek:FeatureEnvy
46
+ # rubocop:disable MethodLength
42
47
  def initialize(user_options = {})
43
- if user_options.respond_to?(:to_i)
44
- @options = { transaction_id: user_options.to_i,
45
- message_type: 5 }
46
- elsif user_options.respond_to?(:[])
47
- @options = user_options.dup.merge(message_type: 5)
48
- handle_user_hash_options
49
- else
50
- fail TypeError
48
+ options = if user_options.respond_to?(:to_i)
49
+ { open_flow_header: { transaction_id: user_options.to_i } }
50
+ elsif user_options.respond_to?(:fetch)
51
+ transaction_id =
52
+ user_options[:transaction_id] || user_options[:xid] || 0
53
+ { open_flow_header: { transaction_id: transaction_id } }
54
+ else
55
+ fail TypeError
56
+ end
57
+ if options[:open_flow_header][:transaction_id] >= 2**32
58
+ fail ArgumentError, 'Transaction ID >= 2**32'
51
59
  end
52
- @features = Format.new(@options)
53
- end
54
-
55
- private
56
-
57
- def handle_user_hash_options
58
- @options[:transaction_id] ||= @options[:xid]
59
- @options[:transaction_id] = 0 unless @options[:transaction_id]
60
+ @format = Format.new(options)
60
61
  end
62
+ # rubocop:enable MethodLength
61
63
  end
62
64
  end
63
65
  end
@@ -1,22 +1,11 @@
1
- # encoding: utf-8
2
-
3
1
  require 'English'
4
- require 'forwardable'
5
2
  require 'pio/hello/format'
3
+ require 'pio/parse_error'
4
+ require 'pio/open_flow'
6
5
 
7
6
  module Pio
8
7
  # OpenFlow 1.0 Hello message
9
- class Hello
10
- extend Forwardable
11
-
12
- def_delegators :@data, :ofp_version
13
- def_delegators :@data, :message_type
14
- def_delegators :@data, :message_length
15
- def_delegators :@data, :transaction_id
16
- def_delegator :@data, :transaction_id, :xid
17
- def_delegators :@data, :body
18
- def_delegator :@data, :to_binary_s, :to_binary
19
-
8
+ class Hello < Pio::OpenFlow::Message
20
9
  # Parses +raw_data+ binary string into a Hello message object.
21
10
  #
22
11
  # @example
@@ -24,12 +13,10 @@ module Pio
24
13
  # @return [Pio::Hello]
25
14
  def self.read(raw_data)
26
15
  hello = allocate
27
- begin
28
- hello.instance_variable_set :@data, Format.read(raw_data)
29
- rescue BinData::ValidityError
30
- raise ParseError, $ERROR_INFO.message
31
- end
16
+ hello.instance_variable_set :@format, Format.read(raw_data)
32
17
  hello
18
+ rescue BinData::ValidityError
19
+ raise Pio::ParseError, $ERROR_INFO.message
33
20
  end
34
21
 
35
22
  # Creates a Hello OpenFlow message.
@@ -52,17 +39,18 @@ module Pio
52
39
  # @param [Hash] user_options The options to create a message with.
53
40
  # @option user_options [Number] :transaction_id
54
41
  # @option user_options [Number] :xid An alias to transaction_id.
42
+ #
43
+ # @reek This method smells of :reek:FeatureEnvy
55
44
  def initialize(user_options = {})
56
- if user_options.respond_to?(:to_i)
57
- @options = { transaction_id: user_options.to_i }
58
- elsif user_options.respond_to?(:[])
59
- @options = user_options.dup
60
- @options[:transaction_id] ||= @options[:xid]
61
- @options[:transaction_id] = 0 unless @options[:transaction_id]
62
- else
63
- fail TypeError
64
- end
65
- @data = Format.new(@options)
45
+ options = if user_options.respond_to?(:to_i)
46
+ { transaction_id: user_options.to_i }
47
+ elsif user_options.respond_to?(:fetch)
48
+ { transaction_id: user_options[:transaction_id] ||
49
+ user_options[:xid] || 0 }
50
+ else
51
+ fail TypeError
52
+ end
53
+ @format = Format.new(open_flow_header: options)
66
54
  end
67
55
  end
68
56
  end