-
Notifications
You must be signed in to change notification settings - Fork 11
/
hello.rb
85 lines (68 loc) · 2.02 KB
/
hello.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require 'pio/open_flow'
# Base module.
module Pio
remove_const :Hello if const_defined?(:Hello)
# OpenFlow 1.3 Hello message parser and generator
class Hello < OpenFlow::Message
VERSION_BITMAP = 1
# ofp_hello_elem_header and value
class Element < BinData::Record
endian :big
uint16 :element_type
uint16 :element_length
choice :element_value, selection: :chooser do
string 'unknown', read_length: -> { element_length - 4 }
uint32 'version_bitmap'
end
def version_bitmap?
element_type == VERSION_BITMAP
end
private
def chooser
version_bitmap? ? 'version_bitmap' : 'unknown'
end
end
# OpenFlow 1.3 Hello message body.
class Body < BinData::Record
array :elements, type: :element, read_until: :eof
def length
if elements.empty?
0
else
elements.length * 4 + 4
end
end
end
# OpenFlow 1.3 Hello message format
class Format < BinData::Record
extend OpenFlow::Format
header version: 4, message_type: 0
body :body
def supported_versions
supported_versions_list.map do |each|
"open_flow1#{each - 1}".to_sym
end
end
private
def supported_versions_list
(1..32).each_with_object([]) do |each, result|
result << each if (version_bitmap >> each & 1) == 1
end
end
def version_bitmap
bitmap = elements.find(&:version_bitmap?)
bitmap ? bitmap.element_value : 0
end
end
user_option :transaction_id
user_option :xid
def initialize(user_options = {})
validate_user_options user_options
header_options = OpenFlowHeader::Options.parse(user_options)
body_options = { elements: [{ element_type: VERSION_BITMAP,
element_length: 8,
element_value: 0b10000 }] }
@format = Format.new(header: header_options, body: body_options)
end
end
end