java_gen: work in progress commit of java generator
diff --git a/java_gen/.gitignore b/java_gen/.gitignore
new file mode 100644
index 0000000..84c1d8e
--- /dev/null
+++ b/java_gen/.gitignore
@@ -0,0 +1,2 @@
+*.class
+bin/
diff --git a/java_gen/__init__.py b/java_gen/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/java_gen/__init__.py
diff --git a/java_gen/java_code_gen.py b/java_gen/java_code_gen.py
new file mode 100644
index 0000000..91c89a7
--- /dev/null
+++ b/java_gen/java_code_gen.py
@@ -0,0 +1,68 @@
+import of_g
+import pdb
+import os
+
+import lang_java
+
+import loxi_utils.loxi_utils as loxi_utils
+
+import java_gen.msgs as msgs
+import java_gen.java_utils as java_utils
+
+def gen_all_java(out, name):
+ """ Generate all of the java files
+
+ @param out is an open file handle to a file called README
+ @param name should be 'README' and is ignored for the java
+ driver
+ """
+ messages = list()
+ actions = list()
+ instructions = list()
+ matches = list()
+ stat_types = list()
+ queue_prop = list()
+ lists = list()
+ for cls in of_g.unified:
+ print "! Classifying %s" % cls
+ if cls in [ 'of_stats_reply', 'of_flow_mod', 'of_stats_request' ] :
+ continue # doesn't work?!
+ if loxi_utils.class_is_stats_message(cls):
+ stat_types.append(cls)
+ elif loxi_utils.class_is_message(cls):
+ messages.append(cls)
+ elif loxi_utils.class_is_action(cls):
+ actions.append(cls)
+ elif loxi_utils.class_is_instruction(cls):
+ instructions.append(cls)
+ elif loxi_utils.class_is_oxm(cls):
+ matches.append(cls)
+ elif loxi_utils.class_is_queue_prop(cls):
+ queue_prop.append(cls)
+ elif loxi_utils.class_is_list(cls):
+ lists.append(cls)
+ else:
+ print "Skipping Unknown class object %s" % str(cls)
+ print "Parsed "
+ print " Messages: %d" % len(messages)
+ print " Actions: %d" % len(actions)
+ print " Instructions: %d" % len(instructions)
+ print " OXM matches: %d" % len(matches)
+ print " Stat types: %d" % len(stat_types)
+ print " Queue properties: %d" % len(queue_prop)
+ print " Lists: %d" % len(lists)
+ target_dir='loxi_output/openflowj'
+ basedir="%s/%s/" % (
+ target_dir,
+ lang_java.file_to_subdir_map['base_java'])
+ srcdir = "%s/src/main/java/org/openflow/protocol" % basedir
+ print "Outputting to %s" % basedir
+ if not os.path.exists(basedir):
+ os.makedirs(basedir)
+ java_utils.copy_prewrite_tree(basedir)
+ msgs.create_message_interfaces(messages,srcdir)
+ msgs.create_message_by_version(messages,srcdir)
+ msgs.create_of_type_enum(messages,srcdir)
+ with open('README.java-lang') as readme_src:
+ out.writelines(readme_src.readlines())
+ out.close()
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
new file mode 100644
index 0000000..062a64d
--- /dev/null
+++ b/java_gen/java_model.py
@@ -0,0 +1,180 @@
+# Prototype of an Intermediate Object model for the java code generator
+# A lot of this stuff could/should probably be merged with the python utilities
+
+import of_g
+import os
+import pdb
+import re
+
+import loxi_front_end.type_maps as type_maps
+import loxi_utils.loxi_utils as utils
+import py_gen.util as py_utils
+
+import java_gen.java_utils as java_utils
+ignore_fields = ['version', 'xid', 'length', 'type' ]
+
+protected_fields = ['version', 'length']
+
+class JavaOFVersion(object):
+ """ Models a version of OpenFlow. contains methods to convert the internal
+ Loxi version to a java constant / a string """
+ def __init__(self, int_version):
+ self.int_version = int(int_version)
+
+ @property
+ def of_version(self):
+ return "1" + str(int(self.int_version) - 1)
+
+ @property
+ def constant_version(self):
+ return "OF_" + self.of_version
+
+ def __str__(self):
+ return of_g.param_version_names[self.int_version]
+
+class JavaProperty(object):
+ """ Models a property (member) of an openflow class. """
+ def __init__(self, msg, java_type, c_type, name, c_name):
+ self.msg = msg
+ self.java_type = java_type
+ self.c_type = c_type
+ self.name = name
+ self.c_name = c_name
+
+ @property
+ def title_name(self):
+ return self.name[0].upper() + self.name[1:]
+
+ @property
+ def constant_name(self):
+ return self.c_name.upper()
+
+ @property
+ def default_name(self):
+ return "DEFAULT_"+self.constant_name
+
+ @property
+ def default_value(self):
+ java_type = self.java_type.public_type;
+
+ if re.match(r'List.*', java_type):
+ return "Collections.emptyList()"
+ elif java_type == "boolean":
+ return "false";
+ elif java_type in ("byte", "char", "short", "int", "long"):
+ return "({0}) 0".format(java_type);
+ else:
+ return "null";
+
+ @property
+ def is_pad(self):
+ return self.c_name.startswith("pad")
+
+ @property
+ def length(self):
+ count, base = utils.type_dec_to_count_base(self.c_type)
+ return of_g.of_base_types[base]['bytes'] * count
+
+ @staticmethod
+ def for_field(msg, field, c_name=None):
+ if not c_name:
+ c_name = field['name']
+
+ name = java_utils.name_c_to_camel(c_name)
+ java_type = java_utils.convert_to_jtype(msg.c_name, c_name, field['m_type'])
+ c_type = field['m_type']
+ return JavaProperty(msg, java_type, c_type, name, c_name)
+
+ @property
+ def is_universal(self):
+ for version in of_g.unified[self.msg.c_name]:
+ if version == 'union' or version =='object_id':
+ continue
+ if 'use_version' in of_g.unified[self.msg.c_name][version]:
+ continue
+
+ if not self.c_name in (f['name'] for f in of_g.unified[self.msg.c_name][version]['members']):
+ return False
+ return True
+
+class JavaOFMessage(object):
+ """ Models an OpenFlow Message class """
+ def __init__(self, c_name):
+ self.c_name = c_name
+ self.interface_name = java_utils.name_c_to_caps_camel(c_name)
+ self.builder_name = self.interface_name + "Builder"
+ self.constant_name = c_name.upper().replace("OF_", "")
+
+ def min_length(self, version):
+ return of_g.base_length[(self.c_name, version.int_version)] if (self.c_name, version.int_version) in of_g.base_length else -1
+
+ def is_fixed_length(self, version):
+ return (self.c_name, version.int_version) in of_g.is_fixed_length
+
+ def class_name_for_version(self, version):
+ return self.interface_name + "Ver"+version.of_version
+
+
+ def all_properties(self, skip_pads=True):
+ if 'union' in of_g.unified[self.c_name]:
+ props = []
+ fields = of_g.unified[self.c_name]['union']
+ for field_name in sorted( fields.keys(), key=lambda k: fields[k]['memid']):
+ if field_name in ignore_fields:
+ continue
+ if skip_pads and field_name.startswith("pad"):
+ continue
+
+ java_property = JavaProperty.for_field(self, fields[field_name], c_name=field_name)
+ props.append(java_property)
+ return props
+ else:
+ return []
+
+ def all_versions(self):
+ return [ JavaOFVersion(int_version)
+ for int_version in of_g.unified[self.c_name]
+ if int_version != 'union' and int_version != 'object_id' ]
+
+ def property_in_version(self, prop, version):
+ if self.version_is_inherited(version):
+ version = self.inherited_from(version)
+
+ if 'members' not in of_g.unified[self.c_name][version.int_version]:
+ return False
+ return prop.c_name in (member['name'] for member in of_g.unified[self.c_name][version.int_version]['members'])
+
+ def properties_for_version(self, version, skip_pads=True):
+ props = []
+ if self.version_is_inherited(version):
+ version = self.inherited_from(version)
+
+ for field in of_g.unified[self.c_name][version.int_version]['members']:
+ if field['name'] in ignore_fields:
+ continue
+ if skip_pads and field['name'].startswith("pad"):
+ continue
+
+ java_property = JavaProperty.for_field(self, field, c_name=field['name'])
+ props.append(java_property)
+ return props
+
+ def version_is_inherited(self, version):
+ return 'use_version' in of_g.unified[self.c_name][version.int_version]
+
+ def inherited_from(self, version):
+ return JavaOFVersion(of_g.unified[self.c_name][version.int_version]['use_version'])
+
+ @property
+ def is_virtual(self):
+ return type_maps.class_is_virtual(self.c_name)
+
+ @property
+ def is_extension(self):
+ return type_maps.message_is_extension(self.c_name, -1)
+
+ def wire_type(self, version):
+ try:
+ return py_utils.primary_wire_type(self.c_name, version.int_version)
+ except ValueError, e:
+ return -1
diff --git a/java_gen/java_utils.py b/java_gen/java_utils.py
new file mode 100644
index 0000000..c55b275
--- /dev/null
+++ b/java_gen/java_utils.py
@@ -0,0 +1,215 @@
+import os
+import errno
+import re
+import subprocess
+import time
+
+def name_c_to_camel(name):
+ """ 'of_stats_reply' -> 'ofStatsReply' """
+ tokens = name.split('_')
+ for i in range(1, len(tokens)):
+ tokens[i] = tokens[i].title()
+ return "".join(tokens)
+
+def name_c_to_caps_camel(name):
+ """ 'of_stats_reply' to 'OFStatsReply' """
+ camel = name_c_to_camel(name.title())
+ if camel.startswith('Of'):
+ return camel.replace('Of','OF',1)
+ else:
+ return camel
+
+
+class JType(object):
+ """ Wrapper class to hold C to Java type conversion information """
+ def __init__(self, pub_type, priv_type=None, size=None, read_op=None, write_op=None):
+ self.pub_type = pub_type # the type we expose externally, e.g. 'U8'
+ if priv_type is None:
+ priv_type = pub_type
+ self.priv_type = priv_type # the internal storage type
+ self.size = size # bytes on the wire; None == variable length or hard to calc
+ if read_op is None:
+ read_op = 'ChannelUtils.read%s(this, "$name", bb)' % self.pub_type
+ if write_op is None:
+ write_op = 'ChannelUtils.write($name)'
+ self._read_op = read_op
+ self.write_op = write_op
+
+ @property
+ def public_type(self):
+ """ return the public type """
+ return self.pub_type
+
+ def priv(self):
+ """ return the public type """
+ return self.priv_type
+
+ def has_priv(self):
+ """ Is the private type different from the public one?"""
+ return self.pub_type != self.priv_type
+
+ def read_op(self, version=None):
+ if callable(self._read_op):
+ return self._read_op(version)
+ else:
+ return self._read_op
+
+hello_elem_list = JType("List<OFHelloElement>",
+ read_op = 'ChannelUtils.readHelloElementList(bb)',
+ write_op = 'ChannelUtils.writeHelloElementList(bb)'
+ )
+
+u8 = JType('byte', size=1, read_op='bb.readByte()',
+ write_op='bb.writeByte($name)')
+u16 = JType('int', 'int', size=2, read_op='U16.f(bb.readShort())',
+ write_op='bb.writeShort(U16.t($name))')
+u32 = JType('int', 'int', size=4, read_op='bb.readInt()',
+ write_op='bb.writeInt($name)')
+u64 = JType('U64', 'U64', size=8, read_op='U64.of(bb.readLong())',
+ write_op='bb.writeLong($name.getLong())')
+of_port= JType('OFPort',size=None,
+ read_op=lambda(version): 'OFPort.ofShort(bb.readShort())' if version.int_version < 2 else 'OFPort.ofInt(bb.readInt())',
+ write_op='$name.writeTo(bb)')
+one_byte_array = JType('byte[]', size=1,
+ read_op = 'ChannelUtils.readBytes(bb, 1)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+two_byte_array = JType('byte[]', size=2,
+ read_op = 'ChannelUtils.readBytes(bb, 2)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+three_byte_array = JType('byte[]', size=3,
+ read_op = 'ChannelUtils.readBytes(bb, 3)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+four_byte_array = JType('byte[]', size=4,
+ read_op = 'ChannelUtils.readBytes(bb, 4)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+five_byte_array = JType('byte[]', size=5,
+ read_op = 'ChannelUtils.readBytes(bb, 5)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+six_byte_array = JType('byte[]', size=6,
+ read_op = 'ChannelUtils.readBytes(bb, 6)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+seven_byte_array = JType('byte[]', size=7,
+ read_op = 'ChannelUtils.readBytes(bb, 7)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+actions_list = JType('List<OFAction>', size='ChannelUtils.calcListSize($name)',
+ read_op = 'ChannelUtils.readActionsList(bb, length - MINIMUM_LENGTH)',
+ write_op = 'ChannelUtils.writeList(this, $name)')
+instructions_list = JType('List<OFInstruction>', size='ChannelUtils.calcListSize($name)',
+ read_op = 'ChannelUtils.readInstructionsList(bb, length - MINIMUM_LENGTH)',
+ write_op = 'ChannelUtils.writeList(this, $name)')
+buckets_list = JType('List<OFBucket>', size='ChannelUtils.calcListSize($name)',
+ read_op = 'ChannelUtils.readBucketList(bb, length - MINIMUM_LENGTH)',
+ write_op = 'ChannelUtils.writeList(this, $name)')
+port_desc_list = JType('List<OFPhysicalPort>', size='ChannelUtils.calcListSize($name)',
+ read_op = 'ChannelUtils.readPhysicalPortList(bb, length - MINIMUM_LENGTH)',
+ write_op = 'ChannelUtils.writeList(this, $name)')
+port_desc = JType('OFPhysicalPort', size='$name.getLength()',
+ read_op = 'ChannelUtils.readPhysicalPort(bb)',
+ write_op = 'ChannelUtils.write(this, $name)')
+packet_queue_list = JType('List<OFPacketQueue>', size='ChannelUtils.calcListSize($name)',
+ read_op = 'ChannelUtils.readPacketQueueList(bb, length - MINIMUM_LENGTH)',
+ write_op = 'ChannelUtils.writeList(this, $name)')
+octets = JType('byte[]', size="length - MINIMUM_LENGTH",
+ read_op = 'ChannelUtils.readBytes(bb, length - MINIMUM_LENGTH)',
+ write_op = 'ChannelUtils.writeBytes(bb, this.$name)')
+of_match = JType('Match', size="$name.getLength()",
+ read_op = 'ChannelUtils.readOFMatch(bb)',
+ write_op = 'ChannelUtils.writeOFMatch(this, $name)')
+flow_mod_cmd = JType('OFFlowModCmd', size="$name.getLength()",
+ read_op = 'ChannelUtils.readOFFlowModCmd(bb)',
+ write_op = 'ChannelUtils.writeOFFlowModCmd(this, $name)')
+mac_addr = JType('MacAddress', 'byte[]', size=6,
+ read_op = 'MacAddress.readFrom(bb)',
+ write_op = 'ChannelUtils.writeBytes(bb, $name)')
+bsn_interface_list = JType("List<OFBsnInterface>",
+ read_op = 'ChannelUtils.readBsnInterfaceList(bb)',
+ write_op = 'ChannelUtils.writeBsnInterfaceList(bb)'
+ )
+meter_band_list = JType("List<OFMeterBand>",
+ read_op = 'ChannelUtils.readMeterBandList(bb)',
+ write_op = 'ChannelUtils.writeMeterBandList(bb, $name)'
+ )
+
+
+
+
+
+default_mtype_to_jtype_convert_map = {
+ 'uint8_t' : u8,
+ 'uint16_t' : u16,
+ 'uint32_t' : u32,
+ 'uint64_t' : u64,
+ 'uint8_t[1]' : one_byte_array,
+ 'uint8_t[2]' : two_byte_array,
+ 'uint8_t[3]' : three_byte_array,
+ 'uint8_t[4]' : four_byte_array,
+ 'uint8_t[5]' : five_byte_array,
+ 'uint8_t[6]' : six_byte_array,
+ 'uint8_t[7]' : seven_byte_array,
+ 'of_port_no_t' : of_port,
+ 'of_list_action_t' : actions_list,
+ 'of_list_instruction_t' : instructions_list,
+ 'of_list_bucket_t': buckets_list,
+ 'of_list_port_desc_t' : port_desc_list,
+ 'of_list_packet_queue_t' : packet_queue_list,
+ 'of_octets_t' : octets,
+ 'of_match_t': of_match,
+ 'of_fm_cmd_t': flow_mod_cmd,
+ 'of_mac_addr_t': mac_addr,
+ 'of_port_desc_t': port_desc,
+ 'of_list_bsn_interface_t': bsn_interface_list,
+ 'of_list_hello_elem_t': hello_elem_list,
+ 'of_list_meter_band_t': meter_band_list
+ }
+
+## This is where we drop in special case handling for certain types
+exceptions = {
+ 'OFPacketIn': {
+ 'data' : octets
+ },
+ }
+
+
+def convert_to_jtype(obj_name, field_name, c_type):
+ """ Convert from a C type ("uint_32") to a java type ("U32")
+ and return a JType object with the size, internal type, and marshalling functions"""
+ if obj_name in exceptions and field_name in exceptions[obj_name]:
+ return exceptions[obj_name][field_name]
+ elif c_type in default_mtype_to_jtype_convert_map:
+ return default_mtype_to_jtype_convert_map[c_type]
+ else:
+ print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name)
+ jtype = name_c_to_caps_camel(c_type) # not sure... try to fake it
+ return JType(jtype)
+
+
+def mkdir_p(path):
+ """ Emulates `mkdir -p` """
+ try:
+ os.makedirs(path)
+ except OSError as exc: # Python >2.5
+ if exc.errno == errno.EEXIST:
+ pass
+ else: raise
+
+def copy_file_with_boiler_plate(src_name, dst_name, with_boiler=True):
+ with open("java_gen/pre-written/%s" % src_name, "r") as src:
+ with open(dst_name, "w") as dst:
+ if with_boiler:
+ print_boiler_plate(os.path.basename(dst_name), dst)
+ dst.writelines(src.readlines())
+
+def frob(s, **kwargs):
+ """ Step through string s and for each key in kwargs,
+ replace $key with kwargs[key] in s.
+ """
+ for k,v in kwargs.iteritems():
+ s = s.replace('$%s' % k, v)
+ return s
+
+def copy_prewrite_tree(basedir):
+ """ Recursively copy the directory structure from ./java_gen/pre-write
+ into $basedir"""
+ print "Copying pre-written files into %s" % basedir
+# subprocess.call("cd java_gen/pre-written && tar cpf - . | ( cd ../../%s && tar xvpf - )" % basedir,
+# shell=True)
diff --git a/java_gen/msgs.py b/java_gen/msgs.py
new file mode 100644
index 0000000..3cdef2c
--- /dev/null
+++ b/java_gen/msgs.py
@@ -0,0 +1,55 @@
+import of_g
+import os
+import pdb
+import re
+
+import loxi_front_end.type_maps as type_maps
+import loxi_utils.loxi_utils as utils
+import py_gen.util as py_utils
+
+import java_gen.java_utils as java_utils
+from java_gen.java_model import *
+ignore_fields = ['version', 'xid', 'length', 'type' ]
+
+protected_fields = ['version', 'length']
+
+
+templates_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates')
+
+def render_template(out, name, **context):
+ prefix = '//::(?=[ \t]|$)'
+ utils.render_template(out, name, [templates_dir], context, prefix=prefix)
+
+def create_message_interfaces(message_names, basedir):
+ """ Create the base interfaces for OFMessages"""
+ for msg_name in message_names:
+ msg = JavaOFMessage(msg_name)
+
+ filename = os.path.join(basedir, "%s.java" % msg.interface_name)
+ dirname = os.path.dirname(filename)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+ with open(filename, "w") as f:
+ render_template(f, "message_interface.java", msg=msg)
+
+def create_of_type_enum(message_names, basedir):
+ all_versions = [ JavaOFVersion(v) for v in of_g.target_version_list ]
+ messages = sorted(filter(lambda msg: not msg.is_virtual and not msg.is_extension, [ JavaOFMessage(msg_name) for msg_name in message_names ]), key=lambda msg: msg.wire_type(all_versions[-1]))
+ filename = os.path.join(basedir, "../types/OFType.java")
+ dirname = os.path.dirname(filename)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ with open(filename, "w") as f:
+ render_template(f, "of_type.java", all_messages=messages, all_versions = all_versions)
+
+def create_message_by_version(message_names, basedir):
+ """ Create the OF Messages for each version that implement the above interfaces"""
+ for msg_name in message_names:
+ msg = JavaOFMessage(msg_name)
+
+ for version in msg.all_versions():
+ filename = os.path.join(basedir, "%s.java" % msg.class_name_for_version(version))
+ with open(filename, "w") as f:
+ render_template(f, "message_class.java", msg=msg, version=version,
+ impl_class=msg.class_name_for_version(version))
diff --git a/java_gen/pre-written/lib/.gitignore b/java_gen/pre-written/lib/.gitignore
new file mode 100644
index 0000000..b4cb1f8
--- /dev/null
+++ b/java_gen/pre-written/lib/.gitignore
@@ -0,0 +1 @@
+netty-3.2.6.Final.jar
diff --git a/java_gen/pre-written/src/main/java/org/openflow/annotations/Immutable.java b/java_gen/pre-written/src/main/java/org/openflow/annotations/Immutable.java
new file mode 100644
index 0000000..1d432c7
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/annotations/Immutable.java
@@ -0,0 +1,13 @@
+package org.openflow.annotations;
+
+/**
+ * This annotation marks a class that is considered externally immutable. I.e.,
+ * the externally visible state of the class will not change after its
+ * construction. Such a class can be freely shared between threads and does not
+ * require defensive copying (don't call clone).
+ *
+ * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ */
+public @interface Immutable {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/exceptions/NonExistantMessage.java b/java_gen/pre-written/src/main/java/org/openflow/exceptions/NonExistantMessage.java
new file mode 100644
index 0000000..2d82ba2
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/exceptions/NonExistantMessage.java
@@ -0,0 +1,30 @@
+package org.openflow.exceptions;
+
+/**
+ * Error: someone asked to create an OFMessage with wireformat type and version,
+ * but that doesn't exist
+ *
+ * @author capveg
+ */
+public class NonExistantMessage extends Exception {
+
+ private static final long serialVersionUID = 1L;
+ byte type;
+ byte version;
+
+ /**
+ * Error: someone asked to create an OFMessage with wireformat type and
+ * version, but that doesn't exist
+ *
+ * @param type
+ * the wire format
+ * @param version
+ * the OpenFlow wireformat version number, e.g. 1 == v1.1, 2 =
+ * v1.2, etc.
+ */
+ public NonExistantMessage(final byte type, final byte version) {
+ this.type = type;
+ this.version = version;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFParseError.java b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFParseError.java
new file mode 100644
index 0000000..76afc79
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFParseError.java
@@ -0,0 +1,22 @@
+package org.openflow.exceptions;
+
+public class OFParseError extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OFParseError() {
+ super();
+ }
+
+ public OFParseError(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public OFParseError(final String message) {
+ super(message);
+ }
+
+ public OFParseError(final Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFShortRead.java b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFShortRead.java
new file mode 100644
index 0000000..3007803
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFShortRead.java
@@ -0,0 +1,6 @@
+package org.openflow.exceptions;
+
+public class OFShortRead extends Exception {
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFShortWrite.java b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFShortWrite.java
new file mode 100644
index 0000000..fb0ddea
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFShortWrite.java
@@ -0,0 +1,7 @@
+package org.openflow.exceptions;
+
+public class OFShortWrite extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFUnsupported.java b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFUnsupported.java
new file mode 100644
index 0000000..14e96db
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/exceptions/OFUnsupported.java
@@ -0,0 +1,7 @@
+package org.openflow.exceptions;
+
+public class OFUnsupported extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/OFAbstractMessage.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFAbstractMessage.java
new file mode 100644
index 0000000..bc2218f
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFAbstractMessage.java
@@ -0,0 +1,83 @@
+/* Copyright 2013, Big Switch Networks, Inc.
+ *
+ * LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+ * the following special exception:
+ *
+ * LOXI Exception
+ *
+ * As a special exception to the terms of the EPL, you may distribute libraries
+ * generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+ * that copyright and licensing notices generated by LoxiGen are not altered or removed
+ * from the LoxiGen Libraries and the notice provided below is (i) included in
+ * the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+ * documentation for the LoxiGen Libraries, if distributed in binary form.
+ *
+ * Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+ *
+ * You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+ * a copy of the EPL at:
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * EPL for the specific language governing permissions and limitations
+ * under the EPL.
+ */
+package org.openflow.protocol;
+
+/**
+ * The base interface for all OpenFlow message objects
+ */
+
+import org.openflow.types.OFType;
+
+abstract public class OFAbstractMessage implements OFObject {
+ private final OFVersion version;
+ private final OFType type;
+ private int xid;
+
+ public static int MINIMUM_SIZE = 8;
+
+ public OFAbstractMessage(final OFVersion version, final OFType type) {
+ this.version = version;
+ this.type = type;
+ }
+
+ /**
+ * Return the wire format version of this message, e.g., 0x01
+ */
+ OFVersion getVersion() {
+ return version;
+ }
+
+ /**
+ * @return the transction ID for this message
+ */
+ int getXid() {
+ return xid;
+ }
+
+ /**
+ * @param newXid
+ * Set this transaction ID for this message
+ */
+ void setXid(final int xid) {
+ this.xid = xid;
+ }
+
+ /**
+ * The type that is returned here is agnostic to the underlying wire format
+ *
+ * @return the type of OpenFlow message.
+ */
+ OFType getType() {
+ return type;
+ }
+
+ @Override
+ public int getLength() {
+ return MINIMUM_SIZE;
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/OFMessage.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFMessage.java
new file mode 100644
index 0000000..4f31741
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFMessage.java
@@ -0,0 +1,13 @@
+package org.openflow.protocol;
+
+import org.openflow.types.OFType;
+
+public interface OFMessage {
+ int getXid();
+
+ boolean isXidSet();
+
+ OFType getType();
+
+ OFVersion getVersion();
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/OFMessageReader.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFMessageReader.java
new file mode 100644
index 0000000..24c3314
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFMessageReader.java
@@ -0,0 +1,8 @@
+package org.openflow.protocol;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+
+public interface OFMessageReader<T extends OFMessage> {
+ T readFrom(ChannelBuffer bb) throws OFParseError;
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/OFObject.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFObject.java
new file mode 100644
index 0000000..21a4607
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFObject.java
@@ -0,0 +1,35 @@
+package org.openflow.protocol;
+
+/**
+ * Base interface of all OpenFlow objects (e.g., messages, actions, stats, etc.)
+ *
+ * All objects have a length and can be read and written from a buffer.
+ * When writing, the length field is dynamically updated, so it need not be
+ * managed manually. However, you can override the auto calculated length with
+ * overrideLength() call, if, for example, you want to intentionally create
+ * malformed packets, for example, for negative testing.
+ */
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortWrite;
+
+public interface OFObject {
+ /**
+ * Return a number equal or greater than zero (and currently in OF less than
+ * 65536)
+ *
+ * @return the number of bytes this object will represent on the wire
+ */
+ public int getLength();
+
+ /**
+ * Automatically calculate any lengths and write an openflow object into the
+ * byte buffer.
+ *
+ * @param bb
+ * A valid byte buffer with sufficient capacity to hold this
+ * object/
+ */
+ public void writeTo(ChannelBuffer bb) throws OFParseError, OFShortWrite;
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/OFObjectFactory.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFObjectFactory.java
new file mode 100644
index 0000000..86cafb1
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFObjectFactory.java
@@ -0,0 +1,7 @@
+package org.openflow.protocol;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+public interface OFObjectFactory<T extends OFObject> {
+ T read(ChannelBuffer buffer);
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/OFVersion.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFVersion.java
new file mode 100644
index 0000000..afc0393
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/OFVersion.java
@@ -0,0 +1,16 @@
+package org.openflow.protocol;
+
+public enum OFVersion {
+ OF_10(1), OF_11(2), OF_12(3), OF_13(4);
+
+ private final int wireVersion;
+
+ OFVersion(final int wireVersion) {
+ this.wireVersion = wireVersion;
+ }
+
+ public int getWireVersion() {
+ return wireVersion;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/actions/OFAction.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/actions/OFAction.java
new file mode 100644
index 0000000..f01f8fe
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/actions/OFAction.java
@@ -0,0 +1,7 @@
+package org.openflow.protocol.actions;
+
+import org.openflow.protocol.OFObject;
+
+public interface OFAction extends OFObject {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/instructions/OFInstruction.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/instructions/OFInstruction.java
new file mode 100644
index 0000000..8af305c
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/instructions/OFInstruction.java
@@ -0,0 +1,7 @@
+package org.openflow.protocol.instructions;
+
+import org.openflow.protocol.OFObject;
+
+public interface OFInstruction extends OFObject {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java
new file mode 100644
index 0000000..5c1e7b5
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java
@@ -0,0 +1,21 @@
+package org.openflow.protocol.match;
+
+import org.openflow.protocol.OFObject;
+
+public interface Match extends OFObject {
+ public <F> F get(MatchField<F, ?> match);
+
+ public <M> M getMasked(MatchField<?, M> match);
+
+ public boolean supports(MatchField<?, ?> field);
+
+ public boolean supportsMasked(MatchField<?, ?> field);
+
+ public boolean isExact(MatchField<?, ?> field);
+
+ public boolean isFullyWildcarded(MatchField<?, ?> field);
+
+ public boolean isPartiallyMasked(MatchField<?, ?> field);
+
+ public MatchBuilder getBuilder();
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchBuilder.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchBuilder.java
new file mode 100644
index 0000000..7a5e57c
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchBuilder.java
@@ -0,0 +1,9 @@
+package org.openflow.protocol.match;
+
+public interface MatchBuilder extends Match {
+ public <F> MatchBuilder set(MatchField<F, ?> match, F value);
+
+ public <M> void setMasked(MatchField<?, M> match, M value);
+
+ public Match getMatch();
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchBuilderVer10.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchBuilderVer10.java
new file mode 100644
index 0000000..19ced8f
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchBuilderVer10.java
@@ -0,0 +1,177 @@
+package org.openflow.protocol.match;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortWrite;
+import org.openflow.protocol.types.IpDscp;
+import org.openflow.types.EthType;
+import org.openflow.types.IPv4;
+import org.openflow.types.IpProtocol;
+import org.openflow.types.MacAddress;
+import org.openflow.types.OFPort;
+import org.openflow.types.U16;
+import org.openflow.types.VlanPcp;
+import org.openflow.types.VlanVid;
+
+public class MatchBuilderVer10 implements MatchBuilder {
+
+ interface BuilderParamHandler<T> {
+ public T get(MatchBuilderVer10 builder);
+
+ public void set(MatchBuilderVer10 builder, T value);
+ }
+
+ // public static Map<MatchField<?,?>, BuilderParamHandler<?>>
+ // handlerMap = new HashMap();
+ static BuilderParamHandler<?>[] handlers = new BuilderParamHandler<?>[2];
+
+ static {
+ handlers[MatchField.IN_PORT.id] = new BuilderParamHandler<OFPort>() {
+ @Override
+ public void set(final MatchBuilderVer10 builder, final OFPort value) {
+ builder.inputPort = value;
+ }
+
+ @Override
+ public OFPort get(final MatchBuilderVer10 builder) {
+ return builder.inputPort;
+ }
+ };
+
+ handlers[MatchField.ETH_SRC.id] = new BuilderParamHandler<MacAddress>() {
+ @Override
+ public void set(final MatchBuilderVer10 builder, final MacAddress value) {
+ builder.dataLayerSource = value;
+ }
+
+ @Override
+ public MacAddress get(final MatchBuilderVer10 builder) {
+ return builder.dataLayerSource;
+ }
+ };
+ }
+
+ protected int wildcards;
+ protected OFPort inputPort;
+ protected MacAddress dataLayerSource;
+ protected MacAddress dataLayerDestination;
+ protected VlanVid dataLayerVirtualLan;
+ protected VlanPcp dataLayerVirtualLanPriorityCodePoint;
+ protected EthType dataLayerType;
+ protected IpDscp ipDscp;
+ protected IpProtocol networkProtocol;
+ protected IPv4 networkSource;
+ protected IPv4 networkDestination;
+ protected U16 transportSource;
+ protected U16 transportDestination;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <F> F get(final MatchField<F, ?> match) {
+ switch (match.id) {
+ case 0:
+ return (F) inputPort;
+ case 1:
+ return (F) dataLayerSource;
+ default:
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <F> MatchBuilder set(final MatchField<F, ?> match, final F value) {
+ switch (match.id) {
+ case 0:
+ inputPort = (OFPort) value;
+ break;
+ case 1:
+ dataLayerSource = (MacAddress) value;
+ break;
+ }
+ return this;
+ }
+
+ public OFPort getInputPort() {
+ return inputPort;
+ }
+
+ public void setInputPort(final OFPort inputPort) {
+ this.inputPort = inputPort;
+ }
+
+ public MacAddress getDataLayerSource() {
+ return dataLayerSource;
+ }
+
+ public void setDataLayerSource(final MacAddress dataLayerSource) {
+ this.dataLayerSource = dataLayerSource;
+ }
+
+ @Override
+ public <M> M getMasked(final MatchField<?, M> match) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean supports(final MatchField<?, ?> field) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean supportsMasked(final MatchField<?, ?> field) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isExact(final MatchField<?, ?> field) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isFullyWildcarded(final MatchField<?, ?> field) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isPartiallyMasked(final MatchField<?, ?> field) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public MatchBuilder getBuilder() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int getLength() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void writeTo(final ChannelBuffer bb) throws OFParseError, OFShortWrite {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public <M> void setMasked(final MatchField<?, M> match, final M value) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Match getMatch() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchField.java
new file mode 100644
index 0000000..b6e8317
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/MatchField.java
@@ -0,0 +1,106 @@
+package org.openflow.protocol.match;
+
+import org.openflow.types.EthType;
+import org.openflow.types.IPv4;
+import org.openflow.types.IPv4WithMask;
+import org.openflow.types.IPv6;
+import org.openflow.types.IPv6WithMask;
+import org.openflow.types.IpProtocol;
+import org.openflow.types.MacAddress;
+import org.openflow.types.MacAddressWithMask;
+import org.openflow.types.OFPort;
+import org.openflow.types.U16;
+import org.openflow.types.U8;
+import org.openflow.types.VlanPcp;
+import org.openflow.types.VlanVid;
+import org.openflow.types.VlanVidWithMask.VlanVidWithMask;
+
+public class MatchField<F, M> {
+ private final String name;
+ public final int id;
+
+ public MatchField(final String name) {
+ this.name = name;
+ this.id = -1;
+ }
+
+ public MatchField(final String name, final int id) {
+ this.name = name;
+ this.id = id;
+ }
+
+ public final static MatchField<OFPort, NoMatch> IN_PORT =
+ new MatchField<OFPort, NoMatch>("in_port", 0);
+ public final static MatchField<OFPort, NoMatch> IN_PHY_PORT =
+ new MatchField<OFPort, NoMatch>("in_phy_port");
+ public final static MatchField<OFPort, NoMatch> METADATA =
+ new MatchField<OFPort, NoMatch>("metadata");
+
+ public final static MatchField<MacAddress, MacAddressWithMask> ETH_DST =
+ new MatchField<MacAddress, MacAddressWithMask>("eth_dst");
+ public final static MatchField<MacAddress, MacAddressWithMask> ETH_SRC =
+ new MatchField<MacAddress, MacAddressWithMask>("eth_src", 1);
+
+ public final static MatchField<EthType, NoMatch> ETH_TYPE =
+ new MatchField<EthType, NoMatch>("eth_type");
+ public final static MatchField<VlanVid, VlanVidWithMask> VLAN_VID =
+ new MatchField<VlanVid, VlanVidWithMask>("vlan_vid");
+ public final static MatchField<VlanPcp, NoMatch> VLAN_PCP =
+ new MatchField<VlanPcp, NoMatch>("vlan_pcp");
+
+ public final static MatchField<NoMatch, NoMatch> IP_DSCP =
+ new MatchField<NoMatch, NoMatch>("ip_dscp");
+ public final static MatchField<NoMatch, NoMatch> IP_ECN =
+ new MatchField<NoMatch, NoMatch>("ip_dscp");
+ public final static MatchField<IpProtocol, NoMatch> IP_PROTO =
+ new MatchField<IpProtocol, NoMatch>("ip_proto");
+
+ public final static MatchField<IPv4, IPv4WithMask> IPV4_SRC =
+ new MatchField<IPv4, IPv4WithMask>("ipv4_src");
+ public final static MatchField<IPv4, IPv4WithMask> IPV4_DST =
+ new MatchField<IPv4, IPv4WithMask>("ipv4_dst");
+
+ public final static MatchField<U16, NoMatch> TCP_SRC = new MatchField<U16, NoMatch>(
+ "tcp_src");
+ public final static MatchField<U16, NoMatch> TCP_DST = new MatchField<U16, NoMatch>(
+ "tcp_dst");
+
+ public final static MatchField<U16, NoMatch> UDP_SRC = new MatchField<U16, NoMatch>(
+ "udp_src");
+ public final static MatchField<U16, NoMatch> UDP_DST = new MatchField<U16, NoMatch>(
+ "udp_dst");
+
+ public final static MatchField<U16, NoMatch> SCTP_SRC = new MatchField<U16, NoMatch>(
+ "sctp_src");
+ public final static MatchField<U16, NoMatch> SCTP_DST = new MatchField<U16, NoMatch>(
+ "sctp_dst");
+
+ public final static MatchField<U8, NoMatch> ICMPV4_TYPE = new MatchField<U8, NoMatch>(
+ "icmpv4_src");
+ public final static MatchField<U8, NoMatch> ICMPV4_CODE = new MatchField<U8, NoMatch>(
+ "icmpv4_dst");
+
+ public final static MatchField<U16, NoMatch> ARP_OP = new MatchField<U16, NoMatch>(
+ "arp_op");
+ public final static MatchField<IPv4, IPv4WithMask> ARP_SPA =
+ new MatchField<IPv4, IPv4WithMask>("arp_spa");
+ public final static MatchField<IPv4, IPv4WithMask> ARP_TPA =
+ new MatchField<IPv4, IPv4WithMask>("arp_tpa");
+ public final static MatchField<MacAddress, MacAddressWithMask> ARP_SHA =
+ new MatchField<MacAddress, MacAddressWithMask>("arp_sha");
+ public final static MatchField<MacAddress, MacAddressWithMask> ARP_THA =
+ new MatchField<MacAddress, MacAddressWithMask>("arp_tha");
+
+ public final static MatchField<IPv6, IPv6WithMask> IPV6_SRC =
+ new MatchField<IPv6, IPv6WithMask>("ipv6_src");
+ public final static MatchField<IPv6, IPv6WithMask> IPV6_DST =
+ new MatchField<IPv6, IPv6WithMask>("ipv6_dst");
+
+ public final static MatchField<U8, IPv6WithMask> IPV6_FLABEL =
+ new MatchField<U8, IPv6WithMask>("ipv6_flabel");
+
+ public String getName() {
+ return name;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/NoMatch.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/NoMatch.java
new file mode 100644
index 0000000..b314a59
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/NoMatch.java
@@ -0,0 +1,5 @@
+package org.openflow.protocol.match;
+
+public class NoMatch {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/types/IpDscp.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/types/IpDscp.java
new file mode 100644
index 0000000..dcc242a
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/types/IpDscp.java
@@ -0,0 +1,5 @@
+package org.openflow.protocol.types;
+
+public class IpDscp {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/EthType.java b/java_gen/pre-written/src/main/java/org/openflow/types/EthType.java
new file mode 100644
index 0000000..d319e57
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/EthType.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class EthType {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/IPv4.java b/java_gen/pre-written/src/main/java/org/openflow/types/IPv4.java
new file mode 100644
index 0000000..b4eb8cf
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/IPv4.java
@@ -0,0 +1,129 @@
+package org.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortRead;
+import org.openflow.exceptions.OFShortWrite;
+import org.openflow.protocol.OFObject;
+
+/**
+ * Wrapper around an IPv4 address
+ *
+ * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ */
+public class IPv4 implements OFObject {
+ static final int LENGTH = 4;
+ private final int rawValue;
+
+ private IPv4(final int rawValue) {
+ this.rawValue = rawValue;
+ }
+
+ public static IPv4 of(final byte[] address) {
+ if (address.length != LENGTH) {
+ throw new IllegalArgumentException(
+ "Invalid byte array length for IPv4 address: " + address);
+ }
+
+ int raw =
+ (address[0] & 0xFF) << 24 | (address[1] & 0xFF) << 16
+ | (address[2] & 0xFF) << 8 | (address[3] & 0xFF) << 0;
+ return IPv4.of(raw);
+ }
+
+ public static IPv4 of(final int raw) {
+ return new IPv4(raw);
+ }
+
+ public static IPv4 of(final String string) {
+ int start = 0;
+ int shift = 24;
+
+ int raw = 0;
+ while (shift >= 0) {
+ int end = string.indexOf('.', start);
+ if (end == start || !((shift > 0) ^ (end < 0)))
+ throw new IllegalArgumentException("IP Address not well formed: " + string);
+
+ String substr =
+ end > 0 ? string.substring(start, end) : string.substring(start);
+ int val = Integer.parseInt(substr);
+ if (val < 0 || val > 255)
+ throw new IllegalArgumentException("IP Address not well formed: " + string);
+
+ raw |= val << shift;
+
+ shift -= 8;
+ start = end + 1;
+ }
+ return IPv4.of(raw);
+ }
+
+ public int getInt() {
+ return rawValue;
+ }
+
+ volatile byte[] bytesCache = null;
+
+ public byte[] getBytes() {
+ if (bytesCache == null) {
+ synchronized (this) {
+ if (bytesCache == null) {
+ bytesCache =
+ new byte[] { (byte) ((rawValue >>> 24) & 0xFF),
+ (byte) ((rawValue >>> 16) & 0xFF),
+ (byte) ((rawValue >>> 8) & 0xFF),
+ (byte) ((rawValue >>> 0) & 0xFF) };
+ }
+ }
+ }
+ return bytesCache;
+ }
+
+ @Override
+ public int getLength() {
+ return LENGTH;
+ }
+
+ public static IPv4 readFrom(final ChannelBuffer bb) throws OFParseError, OFShortRead {
+ return IPv4.of(bb.readInt());
+ }
+
+ @Override
+ public void writeTo(final ChannelBuffer bb) throws OFParseError, OFShortWrite {
+ bb.writeInt(rawValue);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder res = new StringBuilder();
+ res.append((rawValue >> 24) & 0xFF).append('.');
+ res.append((rawValue >> 16) & 0xFF).append('.');
+ res.append((rawValue >> 8) & 0xFF).append('.');
+ res.append((rawValue >> 0) & 0xFF);
+ return res.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + rawValue;
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IPv4 other = (IPv4) obj;
+ if (rawValue != other.rawValue)
+ return false;
+ return true;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/IPv4WithMask.java b/java_gen/pre-written/src/main/java/org/openflow/types/IPv4WithMask.java
new file mode 100644
index 0000000..ec777c0
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/IPv4WithMask.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class IPv4WithMask {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/IPv6.java b/java_gen/pre-written/src/main/java/org/openflow/types/IPv6.java
new file mode 100644
index 0000000..5f51665
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/IPv6.java
@@ -0,0 +1,286 @@
+package org.openflow.types;
+
+import java.util.regex.Pattern;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortRead;
+import org.openflow.exceptions.OFShortWrite;
+import org.openflow.protocol.OFObject;
+
+/**
+ * IPv6 address object. Instance controlled, immutable. Internal representation:
+ * two 64 bit longs (not that you'd have to know).
+ *
+ * @author Andreas Wundsam <andreas.wundsam@teleteach.de>
+ */
+public class IPv6 implements OFObject {
+ static final int LENGTH = 16;
+ private final long raw1;
+ private final long raw2;
+
+ private IPv6(final long raw1, final long raw2) {
+ this.raw1 = raw1;
+ this.raw2 = raw2;
+ }
+
+ public static IPv6 of(final byte[] address) {
+ if (address.length != LENGTH) {
+ throw new IllegalArgumentException(
+ "Invalid byte array length for IPv6 address: " + address);
+ }
+
+ long raw1 =
+ (address[0] & 0xFFL) << 56 | (address[1] & 0xFFL) << 48
+ | (address[2] & 0xFFL) << 40 | (address[3] & 0xFFL) << 32
+ | (address[4] & 0xFFL) << 24 | (address[5] & 0xFFL) << 16
+ | (address[6] & 0xFFL) << 8 | (address[7]);
+
+ long raw2 =
+ (address[8] & 0xFFL) << 56 | (address[9] & 0xFFL) << 48
+ | (address[10] & 0xFFL) << 40 | (address[11] & 0xFFL) << 32
+ | (address[12] & 0xFFL) << 24 | (address[13] & 0xFFL) << 16
+ | (address[14] & 0xFFL) << 8 | (address[15]);
+
+ return IPv6.of(raw1, raw2);
+ }
+
+ private static class IPv6Builder {
+ private long raw1, raw2;
+
+ public void setUnsignedShortWord(final int i, final int value) {
+ int shift = 48 - (i % 4) * 16;
+
+ if (value < 0 || value > 0xFFFF)
+ throw new IllegalArgumentException("16 bit word must be in [0, 0xFFFF]");
+
+ if (i >= 0 && i < 4)
+ raw1 = raw1 & ~(0xFFFFL << shift) | (value & 0xFFFFL) << shift;
+ else if (i >= 4 && i < 8)
+ raw2 = raw2 & ~(0xFFFFL << shift) | (value & 0xFFFFL) << shift;
+ else
+ throw new IllegalArgumentException("16 bit word index must be in [0,7]");
+ }
+
+ public IPv6 getIPv6() {
+ return IPv6.of(raw1, raw2);
+ }
+ }
+
+ private final static Pattern colonPattern = Pattern.compile(":");
+
+ public static IPv6 of(final String string) {
+ IPv6Builder builder = new IPv6Builder();
+ String[] parts = colonPattern.split(string, -1);
+
+ int leftWord = 0;
+ int leftIndex = 0;
+
+ boolean hitZeroCompression = false;
+
+ for (leftIndex = 0; leftIndex < parts.length; leftIndex++) {
+ String part = parts[leftIndex];
+ if (part.length() == 0) {
+ // hit empty group of zero compression
+ hitZeroCompression = true;
+ break;
+ }
+ builder.setUnsignedShortWord(leftWord++, Integer.parseInt(part, 16));
+ }
+
+ if (hitZeroCompression) {
+ if (leftIndex == 0) {
+ // if colon is at the start, two columns must be at the start,
+ // move to the second empty group
+ leftIndex = 1;
+ if (parts.length < 2 || parts[1].length() > 0)
+ throw new IllegalArgumentException("Malformed IPv6 address: " + string);
+ }
+
+ int rightWord = 7;
+ int rightIndex;
+ for (rightIndex = parts.length - 1; rightIndex > leftIndex; rightIndex--) {
+ String part = parts[rightIndex];
+ if (part.length() == 0)
+ break;
+ builder.setUnsignedShortWord(rightWord--, Integer.parseInt(part, 16));
+ }
+ if (rightIndex == parts.length - 1) {
+ // if colon is at the end, two columns must be at the end, move
+ // to the second empty group
+ if (rightIndex < 1 || parts[rightIndex - 1].length() > 0)
+ throw new IllegalArgumentException("Malformed IPv6 address: " + string);
+ rightIndex--;
+ }
+ if (leftIndex != rightIndex)
+ throw new IllegalArgumentException("Malformed IPv6 address: " + string);
+ } else {
+ if (leftIndex != 8) {
+ throw new IllegalArgumentException("Malformed IPv6 address: " + string);
+ }
+ }
+ return builder.getIPv6();
+ }
+
+ public static IPv6 of(final long raw1, final long raw2) {
+ return new IPv6(raw1, raw2);
+ }
+
+ volatile byte[] bytesCache = null;
+
+ public byte[] getBytes() {
+ if (bytesCache == null) {
+ synchronized (this) {
+ if (bytesCache == null) {
+ bytesCache =
+ new byte[] { (byte) ((raw1 >> 56) & 0xFF),
+ (byte) ((raw1 >> 48) & 0xFF),
+ (byte) ((raw1 >> 40) & 0xFF),
+ (byte) ((raw1 >> 32) & 0xFF),
+ (byte) ((raw1 >> 24) & 0xFF),
+ (byte) ((raw1 >> 16) & 0xFF),
+ (byte) ((raw1 >> 8) & 0xFF),
+ (byte) ((raw1 >> 0) & 0xFF),
+
+ (byte) ((raw2 >> 56) & 0xFF),
+ (byte) ((raw2 >> 48) & 0xFF),
+ (byte) ((raw2 >> 40) & 0xFF),
+ (byte) ((raw2 >> 32) & 0xFF),
+ (byte) ((raw2 >> 24) & 0xFF),
+ (byte) ((raw2 >> 16) & 0xFF),
+ (byte) ((raw2 >> 8) & 0xFF),
+ (byte) ((raw2 >> 0) & 0xFF) };
+ }
+ }
+ }
+ return bytesCache;
+ }
+
+ @Override
+ public int getLength() {
+ return LENGTH;
+ }
+
+ public static IPv6 readFrom(final ChannelBuffer bb) throws OFParseError, OFShortRead {
+ return IPv6.of(bb.readLong(), bb.readLong());
+ }
+
+ @Override
+ public void writeTo(final ChannelBuffer bb) throws OFParseError, OFShortWrite {
+ bb.writeLong(raw1);
+ bb.writeLong(raw2);
+ }
+
+ @Override
+ public String toString() {
+ return toString(true, false);
+ }
+
+ public int getUnsignedShortWord(final int i) {
+ if (i >= 0 && i < 4)
+ return (int) ((raw1 >>> (48 - i * 16)) & 0xFFFF);
+ else if (i >= 4 && i < 8)
+ return (int) ((raw2 >>> (48 - (i - 4) * 16)) & 0xFFFF);
+ else
+ throw new IllegalArgumentException("16 bit word index must be in [0,7]");
+ }
+
+ /** get the index of the first word where to apply IPv6 zero compression */
+ public int getZeroCompressStart() {
+ int start = Integer.MAX_VALUE;
+ int maxLength = -1;
+
+ int candidateStart = -1;
+
+ for (int i = 0; i < 8; i++) {
+ if (candidateStart >= 0) {
+ // in a zero octect
+ if (getUnsignedShortWord(i) != 0) {
+ // end of this candidate word
+ int candidateLength = i - candidateStart;
+ if (candidateLength >= maxLength) {
+ start = candidateStart;
+ maxLength = candidateLength;
+ }
+ candidateStart = -1;
+ }
+ } else {
+ // not in a zero octect
+ if (getUnsignedShortWord(i) == 0) {
+ candidateStart = i;
+ }
+ }
+ }
+
+ if (candidateStart >= 0) {
+ int candidateLength = 8 - candidateStart;
+ if (candidateLength >= maxLength) {
+ start = candidateStart;
+ maxLength = candidateLength;
+ }
+ }
+
+ return start;
+ }
+
+ public String toString(final boolean zeroCompression, final boolean leadingZeros) {
+ StringBuilder res = new StringBuilder();
+
+ int compressionStart = zeroCompression ? getZeroCompressStart() : Integer.MAX_VALUE;
+ boolean inCompression = false;
+ boolean colonNeeded = false;
+
+ for (int i = 0; i < 8; i++) {
+ int word = getUnsignedShortWord(i);
+
+ if (word == 0) {
+ if (inCompression)
+ continue;
+ else if (i == compressionStart) {
+ res.append(':').append(':');
+ inCompression = true;
+ colonNeeded = false;
+ continue;
+ }
+ } else {
+ inCompression = false;
+ }
+
+ if (colonNeeded) {
+ res.append(':');
+ colonNeeded = false;
+ }
+
+ res.append(leadingZeros ? String.format("%04x", word) : Integer.toString(word,
+ 16));
+ colonNeeded = true;
+ }
+ return res.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (int) (raw1 ^ (raw1 >>> 32));
+ result = prime * result + (int) (raw2 ^ (raw2 >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IPv6 other = (IPv6) obj;
+ if (raw1 != other.raw1)
+ return false;
+ if (raw2 != other.raw2)
+ return false;
+ return true;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/IPv6WithMask.java b/java_gen/pre-written/src/main/java/org/openflow/types/IPv6WithMask.java
new file mode 100644
index 0000000..0fb3281
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/IPv6WithMask.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class IPv6WithMask {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/IpProtocol.java b/java_gen/pre-written/src/main/java/org/openflow/types/IpProtocol.java
new file mode 100644
index 0000000..a295cb2
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/IpProtocol.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class IpProtocol {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/MacAddress.java b/java_gen/pre-written/src/main/java/org/openflow/types/MacAddress.java
new file mode 100644
index 0000000..4ce19ab
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/MacAddress.java
@@ -0,0 +1,123 @@
+package org.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortWrite;
+import org.openflow.protocol.OFObject;
+import org.openflow.util.HexString;
+
+/**
+ * Wrapper around a 6 byte mac address.
+ *
+ * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ */
+
+public class MacAddress implements OFObject {
+ static final int MacAddrLen = 6;
+ private final long rawValue;
+
+ private MacAddress(final long rawValue) {
+ this.rawValue = rawValue;
+ }
+
+ public static MacAddress of(final byte[] address) {
+ long raw =
+ (address[0] & 0xFFL) << 40 | (address[1] & 0xFFL) << 32
+ | (address[2] & 0xFFL) << 24 | (address[3] & 0xFFL) << 16
+ | (address[4] & 0xFFL) << 8 | (address[5] & 0xFFL);
+ return MacAddress.of(raw);
+ }
+
+ public static MacAddress of(final long raw) {
+ return new MacAddress(raw);
+ }
+
+ public static MacAddress of(final String string) {
+ int index = 0;
+ int shift = 40;
+
+ long raw = 0;
+ if (string.length() != 6 * 2 + 5)
+ throw new IllegalArgumentException("Mac address not well formed: " + string);
+
+ while (shift >= 0) {
+ raw |=
+ ((long) (Character.digit(string.charAt(index++), 16) << 4 | Character
+ .digit(string.charAt(index++), 16))) << shift;
+
+ if (shift == 0)
+ break;
+ if (string.charAt(index++) != ':')
+ throw new IllegalArgumentException("Mac address not well formed: " + string);
+ shift -= 8;
+ }
+ return MacAddress.of(raw);
+ }
+
+ volatile byte[] bytesCache = null;
+
+ public byte[] getBytes() {
+ if (bytesCache == null) {
+ synchronized (this) {
+ if (bytesCache == null) {
+ bytesCache =
+ new byte[] { (byte) ((rawValue >> 40) & 0xFF),
+ (byte) ((rawValue >> 32) & 0xFF),
+ (byte) ((rawValue >> 24) & 0xFF),
+ (byte) ((rawValue >> 16) & 0xFF),
+ (byte) ((rawValue >> 8) & 0xFF),
+ (byte) ((rawValue >> 0) & 0xFF) };
+ }
+ }
+ }
+ return bytesCache;
+ }
+
+ @Override
+ public int getLength() {
+ return MacAddrLen;
+ }
+
+ public static MacAddress readFrom(final ChannelBuffer bb) throws OFParseError {
+ long raw = bb.readUnsignedInt() << 16 | bb.readUnsignedShort();
+ return MacAddress.of(raw);
+ }
+
+ @Override
+ public void writeTo(final ChannelBuffer bb) throws OFParseError, OFShortWrite {
+ bb.writeInt((int) (rawValue >> 16));
+ bb.writeShort((int) rawValue & 0xFFFF);
+ }
+
+ @Override
+ public String toString() {
+ return HexString.toHexString(rawValue, 6);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (int) (rawValue ^ (rawValue >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MacAddress other = (MacAddress) obj;
+ if (rawValue != other.rawValue)
+ return false;
+ return true;
+ }
+
+ public long getLong() {
+ return rawValue;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/MacAddressWithMask.java b/java_gen/pre-written/src/main/java/org/openflow/types/MacAddressWithMask.java
new file mode 100644
index 0000000..ffa5fa7
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/MacAddressWithMask.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class MacAddressWithMask {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/Masked.java b/java_gen/pre-written/src/main/java/org/openflow/types/Masked.java
new file mode 100644
index 0000000..98a8e0b
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/Masked.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class Masked<T> {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFBsnInterface.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFBsnInterface.java
new file mode 100644
index 0000000..d0afb56
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFBsnInterface.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public interface OFBsnInterface {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFBucket.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFBucket.java
new file mode 100644
index 0000000..47b403b
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFBucket.java
@@ -0,0 +1,22 @@
+package org.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortWrite;
+import org.openflow.protocol.OFObject;
+
+public class OFBucket implements OFObject {
+
+ @Override
+ public int getLength() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void writeTo(final ChannelBuffer bb) throws OFParseError, OFShortWrite {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFFlowModCmd.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFFlowModCmd.java
new file mode 100644
index 0000000..6ca2c04
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFFlowModCmd.java
@@ -0,0 +1,11 @@
+package org.openflow.types;
+
+/**
+ * Version agnostic view of commands to an OFFlowMod
+ *
+ * @author capveg
+ */
+
+public enum OFFlowModCmd {
+ ADD, MODIFY, MODIFY_STRICT, DELETE, DELETE_STRICT
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFHelloElement.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFHelloElement.java
new file mode 100644
index 0000000..288e1b6
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFHelloElement.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public interface OFHelloElement {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFMeterBand.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFMeterBand.java
new file mode 100644
index 0000000..d15812b
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFMeterBand.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public interface OFMeterBand {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFPacketQueue.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFPacketQueue.java
new file mode 100644
index 0000000..d74906f
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFPacketQueue.java
@@ -0,0 +1,22 @@
+package org.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortWrite;
+import org.openflow.protocol.OFObject;
+
+public class OFPacketQueue implements OFObject {
+
+ @Override
+ public int getLength() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void writeTo(final ChannelBuffer bb) throws OFParseError, OFShortWrite {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFPhysicalPort.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFPhysicalPort.java
new file mode 100644
index 0000000..0853fea
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFPhysicalPort.java
@@ -0,0 +1,12 @@
+package org.openflow.types;
+
+/**
+ * A wrapper around the OpenFlow physical port description. The interfaces to
+ * this object are version agnostic.
+ *
+ * @author capveg
+ */
+
+public class OFPhysicalPort {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java
new file mode 100644
index 0000000..4156f1f
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java
@@ -0,0 +1,491 @@
+package org.openflow.types;
+
+import org.openflow.annotations.Immutable;
+
+/**
+ * Abstraction of an logical / OpenFlow switch port (ofp_port_no) in OpenFlow.
+ * Immutable. Note: Switch port numbers were changed in OpenFlow 1.1 from uint16
+ * to uint32. This class uses a 32 bit representation internally. Port numbers
+ * are converted from/to uint16 when constructed / getPortNumberasShort is
+ * called. If this port is not representable in OpenFlow 1.0, an
+ * IllegalStateException is raised.
+ *
+ * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ */
+@Immutable
+public class OFPort {
+ // private int constants (OF1.1+) to avoid duplication in the code
+ // should not have to use these outside this class
+ private static final int OFPP_ANY_INT = 0xFFffFFff;
+ private static final int OFPP_LOCAL_INT = 0xFFffFFfe;
+ private static final int OFPP_CONTROLLER_INT = 0xFFffFFfd;
+ private static final int OFPP_ALL_INT = 0xFFffFFfc;
+ private static final int OFPP_FLOOD_INT = 0xFFffFFfb;
+ private static final int OFPP_NORMAL_INT = 0xFFffFFfa;
+ private static final int OFPP_TABLE_INT = 0xFFffFFf9;
+ private static final int OFPP_MAX_INT = 0xFFffFF00;
+ private static final int OFPP_IN_PORT_INT = 0xFFffFFf8;
+
+ // private short constants (OF1.0) to avoid duplication in the code
+ // should not have to use these outside this class
+ private static final short OFPP_ANY_SHORT = (short) 0xFFff;
+ private static final short OFPP_LOCAL_SHORT = (short) 0xFFfe;
+ private static final short OFPP_CONTROLLER_SHORT = (short) 0xFFfd;
+ private static final short OFPP_ALL_SHORT = (short) 0xFFfc;
+ private static final short OFPP_FLOOD_SHORT = (short) 0xFFfb;
+ private static final short OFPP_NORMAL_SHORT = (short) 0xFFfa;
+ private static final short OFPP_TABLE_SHORT = (short) 0xFFf9;
+ private static final short OFPP_IN_PORT_SHORT = (short) 0xFFf8;
+ private static final short OFPP_MAX_SHORT = (short) 0xFF00;
+ private static final int OFPP_MAX_SHORT_UNSIGNED = 0xFF00;
+
+ // ////////////// public constants - use to access well known OpenFlow ports
+
+ /** Maximum number of physical and logical switch ports. */
+ public final static OFPort MAX = new NamedPort(OFPP_MAX_INT, "max");
+
+ /**
+ * Send the packet out the input port. This reserved port must be explicitly
+ * used in order to send back out of the input port.
+ */
+ public final static OFPort IN_PORT = new NamedPort(OFPP_IN_PORT_INT, "in_port");
+
+ /**
+ * Submit the packet to the first flow table NB: This destination port can
+ * only be used in packet-out messages.
+ */
+ public final static OFPort TABLE = new NamedPort(OFPP_TABLE_INT, "table");
+
+ /** Process with normal L2/L3 switching. */
+ public final static OFPort NORMAL = new NamedPort(OFPP_NORMAL_INT, "normal");
+
+ /**
+ * All physical ports in VLAN, except input port and those blocked or link
+ * down
+ */
+ public final static OFPort FLOOD = new NamedPort(OFPP_FLOOD_INT, "flood");
+
+ /** All physical ports except input port */
+ public final static OFPort ALL = new NamedPort(OFPP_ALL_INT, "all");
+
+ /** Send to controller */
+ public final static OFPort CONTROLLER =
+ new NamedPort(OFPP_CONTROLLER_INT, "controller");
+
+ /** local openflow "port" */
+ public final static OFPort LOCAL = new NamedPort(OFPP_LOCAL_INT, "local");
+
+ /**
+ * Wildcard port used only for flow mod (delete) and flow stats requests.
+ * Selects all flows regardless of output port (including flows with no
+ * output port). NOTE: OpenFlow 1.0 calls this 'NONE'
+ */
+ public final static OFPort ANY = new NamedPort(OFPP_ANY_INT, "any");
+
+ /** cache of frequently used ports */
+ private static class PrecachedPort {
+ private final static OFPort p1 = new OFPort(1);
+ private final static OFPort p2 = new OFPort(2);
+ private final static OFPort p3 = new OFPort(3);
+ private final static OFPort p4 = new OFPort(4);
+ private final static OFPort p5 = new OFPort(5);
+ private final static OFPort p6 = new OFPort(6);
+ private final static OFPort p7 = new OFPort(7);
+ private final static OFPort p8 = new OFPort(8);
+ private final static OFPort p9 = new OFPort(9);
+ private final static OFPort p10 = new OFPort(10);
+ private final static OFPort p11 = new OFPort(11);
+ private final static OFPort p12 = new OFPort(12);
+ private final static OFPort p13 = new OFPort(13);
+ private final static OFPort p14 = new OFPort(14);
+ private final static OFPort p15 = new OFPort(15);
+ private final static OFPort p16 = new OFPort(16);
+ private final static OFPort p17 = new OFPort(17);
+ private final static OFPort p18 = new OFPort(18);
+ private final static OFPort p19 = new OFPort(19);
+ private final static OFPort p20 = new OFPort(20);
+ private final static OFPort p21 = new OFPort(21);
+ private final static OFPort p22 = new OFPort(22);
+ private final static OFPort p23 = new OFPort(23);
+ private final static OFPort p24 = new OFPort(24);
+ private final static OFPort p25 = new OFPort(25);
+ private final static OFPort p26 = new OFPort(26);
+ private final static OFPort p27 = new OFPort(27);
+ private final static OFPort p28 = new OFPort(28);
+ private final static OFPort p29 = new OFPort(29);
+ private final static OFPort p31 = new OFPort(31);
+ private final static OFPort p32 = new OFPort(32);
+ private final static OFPort p33 = new OFPort(33);
+ private final static OFPort p34 = new OFPort(34);
+ private final static OFPort p35 = new OFPort(35);
+ private final static OFPort p36 = new OFPort(36);
+ private final static OFPort p37 = new OFPort(37);
+ private final static OFPort p38 = new OFPort(38);
+ private final static OFPort p39 = new OFPort(39);
+ private final static OFPort p40 = new OFPort(40);
+ private final static OFPort p41 = new OFPort(41);
+ private final static OFPort p42 = new OFPort(42);
+ private final static OFPort p43 = new OFPort(43);
+ private final static OFPort p44 = new OFPort(44);
+ private final static OFPort p45 = new OFPort(45);
+ private final static OFPort p46 = new OFPort(46);
+ private final static OFPort p47 = new OFPort(47);
+ private final static OFPort p48 = new OFPort(48);
+ }
+
+ /** raw openflow port number as a signed 32 bit integer */
+ private final int portNumber;
+
+ /** private constructor. use of*-Factory methods instead */
+ private OFPort(final int portNumber) {
+ this.portNumber = portNumber;
+ }
+
+ /**
+ * get an OFPort object corresponding to a raw 32-bit integer port number.
+ * NOTE: The port object may either be newly allocated or cached. Do not
+ * rely on either behavior.
+ *
+ * @param portNumber
+ * @return a corresponding OFPort
+ */
+ public static OFPort ofInt(final int portNumber) {
+ switch (portNumber) {
+ case 1:
+ return PrecachedPort.p1;
+ case 2:
+ return PrecachedPort.p2;
+ case 3:
+ return PrecachedPort.p3;
+ case 4:
+ return PrecachedPort.p4;
+ case 5:
+ return PrecachedPort.p5;
+ case 6:
+ return PrecachedPort.p6;
+ case 7:
+ return PrecachedPort.p7;
+ case 8:
+ return PrecachedPort.p8;
+ case 9:
+ return PrecachedPort.p9;
+ case 10:
+ return PrecachedPort.p10;
+ case 11:
+ return PrecachedPort.p11;
+ case 12:
+ return PrecachedPort.p12;
+ case 13:
+ return PrecachedPort.p13;
+ case 14:
+ return PrecachedPort.p14;
+ case 15:
+ return PrecachedPort.p15;
+ case 16:
+ return PrecachedPort.p16;
+ case 17:
+ return PrecachedPort.p17;
+ case 18:
+ return PrecachedPort.p18;
+ case 19:
+ return PrecachedPort.p19;
+ case 20:
+ return PrecachedPort.p20;
+ case 21:
+ return PrecachedPort.p21;
+ case 22:
+ return PrecachedPort.p22;
+ case 23:
+ return PrecachedPort.p23;
+ case 24:
+ return PrecachedPort.p24;
+ case 25:
+ return PrecachedPort.p25;
+ case 26:
+ return PrecachedPort.p26;
+ case 27:
+ return PrecachedPort.p27;
+ case 28:
+ return PrecachedPort.p28;
+ case 29:
+ return PrecachedPort.p29;
+ case 31:
+ return PrecachedPort.p31;
+ case 32:
+ return PrecachedPort.p32;
+ case 33:
+ return PrecachedPort.p33;
+ case 34:
+ return PrecachedPort.p34;
+ case 35:
+ return PrecachedPort.p35;
+ case 36:
+ return PrecachedPort.p36;
+ case 37:
+ return PrecachedPort.p37;
+ case 38:
+ return PrecachedPort.p38;
+ case 39:
+ return PrecachedPort.p39;
+ case 40:
+ return PrecachedPort.p40;
+ case 41:
+ return PrecachedPort.p41;
+ case 42:
+ return PrecachedPort.p42;
+ case 43:
+ return PrecachedPort.p43;
+ case 44:
+ return PrecachedPort.p44;
+ case 45:
+ return PrecachedPort.p45;
+ case 46:
+ return PrecachedPort.p46;
+ case 47:
+ return PrecachedPort.p47;
+ case 48:
+ return PrecachedPort.p48;
+ case OFPP_MAX_INT:
+ return MAX;
+ case OFPP_IN_PORT_INT:
+ return IN_PORT;
+ case OFPP_TABLE_INT:
+ return TABLE;
+ case OFPP_NORMAL_INT:
+ return NORMAL;
+ case OFPP_FLOOD_INT:
+ return FLOOD;
+ case OFPP_ALL_INT:
+ return ALL;
+ case OFPP_CONTROLLER_INT:
+ return CONTROLLER;
+ case OFPP_LOCAL_INT:
+ return LOCAL;
+ case OFPP_ANY_INT:
+ return ANY;
+ default:
+ // note: This means effectively : portNumber > OFPP_MAX_SHORT
+ // accounting for
+ // signedness of both portNumber and OFPP_MAX_INT(which is
+ // -256).
+ // Any unsigned integer value > OFPP_MAX_INT will be ]-256:0[
+ // when read signed
+ if (portNumber < 0 && portNumber > OFPP_MAX_INT)
+ throw new IllegalArgumentException("Unknown special port number: "
+ + portNumber);
+ return new OFPort(portNumber);
+ }
+ }
+
+ /** convenience function: delegates to ofInt */
+ public static OFPort of(final int portNumber) {
+ return ofInt(portNumber);
+ }
+
+ /**
+ * get an OFPort object corresponding to a raw signed 16-bit integer port
+ * number (OF1.0). Note that the port returned will have the corresponding
+ * 32-bit integer value allocated as its port number. NOTE: The port object
+ * may either be newly allocated or cached. Do not rely on either behavior.
+ *
+ * @param portNumber
+ * @return a corresponding OFPort
+ */
+ public static OFPort ofShort(final short portNumber) {
+ switch (portNumber) {
+ case 1:
+ return PrecachedPort.p1;
+ case 2:
+ return PrecachedPort.p2;
+ case 3:
+ return PrecachedPort.p3;
+ case 4:
+ return PrecachedPort.p4;
+ case 5:
+ return PrecachedPort.p5;
+ case 6:
+ return PrecachedPort.p6;
+ case 7:
+ return PrecachedPort.p7;
+ case 8:
+ return PrecachedPort.p8;
+ case 9:
+ return PrecachedPort.p9;
+ case 10:
+ return PrecachedPort.p10;
+ case 11:
+ return PrecachedPort.p11;
+ case 12:
+ return PrecachedPort.p12;
+ case 13:
+ return PrecachedPort.p13;
+ case 14:
+ return PrecachedPort.p14;
+ case 15:
+ return PrecachedPort.p15;
+ case 16:
+ return PrecachedPort.p16;
+ case 17:
+ return PrecachedPort.p17;
+ case 18:
+ return PrecachedPort.p18;
+ case 19:
+ return PrecachedPort.p19;
+ case 20:
+ return PrecachedPort.p20;
+ case 21:
+ return PrecachedPort.p21;
+ case 22:
+ return PrecachedPort.p22;
+ case 23:
+ return PrecachedPort.p23;
+ case 24:
+ return PrecachedPort.p24;
+ case 25:
+ return PrecachedPort.p25;
+ case 26:
+ return PrecachedPort.p26;
+ case 27:
+ return PrecachedPort.p27;
+ case 28:
+ return PrecachedPort.p28;
+ case 29:
+ return PrecachedPort.p29;
+ case 31:
+ return PrecachedPort.p31;
+ case 32:
+ return PrecachedPort.p32;
+ case 33:
+ return PrecachedPort.p33;
+ case 34:
+ return PrecachedPort.p34;
+ case 35:
+ return PrecachedPort.p35;
+ case 36:
+ return PrecachedPort.p36;
+ case 37:
+ return PrecachedPort.p37;
+ case 38:
+ return PrecachedPort.p38;
+ case 39:
+ return PrecachedPort.p39;
+ case 40:
+ return PrecachedPort.p40;
+ case 41:
+ return PrecachedPort.p41;
+ case 42:
+ return PrecachedPort.p42;
+ case 43:
+ return PrecachedPort.p43;
+ case 44:
+ return PrecachedPort.p44;
+ case 45:
+ return PrecachedPort.p45;
+ case 46:
+ return PrecachedPort.p46;
+ case 47:
+ return PrecachedPort.p47;
+ case 48:
+ return PrecachedPort.p48;
+ case OFPP_MAX_SHORT:
+ return MAX;
+ case OFPP_IN_PORT_SHORT:
+ return IN_PORT;
+ case OFPP_TABLE_SHORT:
+ return TABLE;
+ case OFPP_NORMAL_SHORT:
+ return NORMAL;
+ case OFPP_FLOOD_SHORT:
+ return FLOOD;
+ case OFPP_ALL_SHORT:
+ return ALL;
+ case OFPP_CONTROLLER_SHORT:
+ return CONTROLLER;
+ case OFPP_LOCAL_SHORT:
+ return LOCAL;
+ case OFPP_ANY_SHORT:
+ return ANY;
+ default:
+ // note: This means effectively : portNumber > OFPP_MAX_SHORT
+ // accounting for
+ // signedness of both portNumber and OFPP_MAX_SHORT (which is
+ // -256).
+ // Any unsigned integer value > OFPP_MAX_SHORT will be ]-256:0[
+ // when read signed
+ if (portNumber < 0 && portNumber > OFPP_MAX_SHORT)
+ throw new IllegalArgumentException("Unknown special port number: "
+ + portNumber);
+ return new OFPort(portNumber);
+ }
+ }
+
+ /** return the port number as a int32 */
+ public int getPortNumber() {
+ return portNumber;
+ }
+
+ /**
+ * return the port number as int16. Special ports as defined by the OpenFlow
+ * spec will be converted to their OpenFlow 1.0 equivalent. port numbers >=
+ * FF00 will cause a IllegalArgumentException to be thrown
+ *
+ * @throws IllegalArgumentException
+ * if a regular port number exceeds the maximum value in OF1.0
+ **/
+ public short getShortPortNumber() {
+
+ switch (portNumber) {
+ case OFPP_MAX_INT:
+ return OFPP_MAX_SHORT;
+ case OFPP_IN_PORT_INT:
+ return OFPP_IN_PORT_SHORT;
+ case OFPP_TABLE_INT:
+ return OFPP_TABLE_SHORT;
+ case OFPP_NORMAL_INT:
+ return OFPP_NORMAL_SHORT;
+ case OFPP_FLOOD_INT:
+ return OFPP_FLOOD_SHORT;
+ case OFPP_ALL_INT:
+ return OFPP_ALL_SHORT;
+ case OFPP_CONTROLLER_INT:
+ return OFPP_CONTROLLER_SHORT;
+ case OFPP_LOCAL_INT:
+ return OFPP_LOCAL_SHORT;
+ case OFPP_ANY_INT:
+ return OFPP_ANY_SHORT;
+
+ default:
+ if (portNumber >= OFPP_MAX_SHORT_UNSIGNED || portNumber < 0)
+ throw new IllegalArgumentException("32bit Port number "
+ + U32.f(portNumber)
+ + " cannot be represented as uint16 (OF1.0)");
+
+ return (short) portNumber;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return Long.toString(U32.f(portNumber));
+ }
+
+ /** Extension of OFPort for named ports */
+ static class NamedPort extends OFPort {
+ private final String name;
+
+ NamedPort(final int portNo, final String name) {
+ super(portNo);
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/U16.java b/java_gen/pre-written/src/main/java/org/openflow/types/U16.java
new file mode 100644
index 0000000..5884adc
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/U16.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.types;
+
+public class U16 {
+ public static int f(final short i) {
+ return i & 0xffff;
+ }
+
+ public static short t(final int l) {
+ return (short) l;
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/U32.java b/java_gen/pre-written/src/main/java/org/openflow/types/U32.java
new file mode 100644
index 0000000..003f35d
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/U32.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.types;
+
+public class U32 {
+ public static long f(final int i) {
+ return i & 0xffffffffL;
+ }
+
+ public static int t(final long l) {
+ return (int) l;
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/U64.java b/java_gen/pre-written/src/main/java/org/openflow/types/U64.java
new file mode 100644
index 0000000..211c3ea
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/U64.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.types;
+
+import java.math.BigInteger;
+
+public class U64 {
+ private final static BigInteger TWO_POWER_64 = BigInteger.valueOf(Long.MAX_VALUE).add(
+ BigInteger.valueOf(1));
+
+ private final long raw;
+
+ private U64(final long raw) {
+ this.raw = raw;
+ }
+
+ public static U64 of(final long raw) {
+ return new U64(raw);
+ }
+
+ public long getValue() {
+ return raw;
+ }
+
+ public BigInteger getBigInteger() {
+ return raw >= 0 ? BigInteger.valueOf(raw) : TWO_POWER_64.add(BigInteger
+ .valueOf(raw));
+ }
+
+ @Override
+ public String toString() {
+ return getBigInteger().toString();
+ }
+
+ public static BigInteger f(final long i) {
+ return new BigInteger(Long.toBinaryString(i), 2);
+ }
+
+ public static long t(final BigInteger l) {
+ return l.longValue();
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/U8.java b/java_gen/pre-written/src/main/java/org/openflow/types/U8.java
new file mode 100644
index 0000000..1cdf0e5
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/U8.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.types;
+
+public class U8 {
+ byte data;
+
+ public static short f(final byte i) {
+ return (short) (i & 0xff);
+ }
+
+ public static byte t(final short l) {
+ return (byte) l;
+ }
+
+ public byte getValue() {
+ return data;
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/VlanPcp.java b/java_gen/pre-written/src/main/java/org/openflow/types/VlanPcp.java
new file mode 100644
index 0000000..bda2dc1
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/VlanPcp.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class VlanPcp {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/VlanVid.java b/java_gen/pre-written/src/main/java/org/openflow/types/VlanVid.java
new file mode 100644
index 0000000..0f9eaf7
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/VlanVid.java
@@ -0,0 +1,5 @@
+package org.openflow.types;
+
+public class VlanVid {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/VlanVidWithMask/VlanVidWithMask.java b/java_gen/pre-written/src/main/java/org/openflow/types/VlanVidWithMask/VlanVidWithMask.java
new file mode 100644
index 0000000..610b11c
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/VlanVidWithMask/VlanVidWithMask.java
@@ -0,0 +1,5 @@
+package org.openflow.types.VlanVidWithMask;
+
+public class VlanVidWithMask {
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java b/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java
new file mode 100644
index 0000000..e8eeebd
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java
@@ -0,0 +1,93 @@
+package org.openflow.util;
+
+import java.util.List;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.protocol.actions.OFAction;
+import org.openflow.protocol.instructions.OFInstruction;
+import org.openflow.protocol.match.Match;
+import org.openflow.types.OFBsnInterface;
+import org.openflow.types.OFBucket;
+import org.openflow.types.OFFlowModCmd;
+import org.openflow.types.OFHelloElement;
+import org.openflow.types.OFMeterBand;
+import org.openflow.types.OFPacketQueue;
+import org.openflow.types.OFPhysicalPort;
+
+/**
+ * Collection of helper functions for reading and writing into ChannelBuffers
+ *
+ * @author capveg
+ */
+
+public class ChannelUtils {
+
+ static public byte[] readBytes(final ChannelBuffer bb, final int length) {
+ byte byteArray[] = new byte[length];
+ bb.readBytes(byteArray);
+ return byteArray;
+ }
+
+ static public void writeBytes(final ChannelBuffer bb, final byte byteArray[]) {
+ bb.writeBytes(byteArray);
+ }
+
+ public static List<OFPhysicalPort> readPhysicalPortList(final ChannelBuffer bb,
+ final int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFInstruction> readInstructionsList(final ChannelBuffer bb,
+ final int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static Match readOFMatch(final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static OFFlowModCmd readOFFlowModCmd(final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFAction> readActionsList(final ChannelBuffer bb, final int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFBsnInterface> readBsnInterfaceList(final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static OFPhysicalPort readPhysicalPort(final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFPacketQueue> readPacketQueueList(final ChannelBuffer bb,
+ final int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFHelloElement> readHelloElementList(final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFBucket> readBucketList(final ChannelBuffer bb, final int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFMeterBand> readMeterBandList(final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/util/HexString.java b/java_gen/pre-written/src/main/java/org/openflow/util/HexString.java
new file mode 100644
index 0000000..8d17132
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/util/HexString.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.util;
+
+import java.math.BigInteger;
+
+import org.openflow.types.U8;
+
+public class HexString {
+ /**
+ * Convert a string of bytes to a ':' separated hex string
+ *
+ * @param bytes
+ * @return "0f:ca:fe:de:ad:be:ef"
+ */
+ public static String toHexString(final byte[] bytes) {
+ int i;
+ String ret = "";
+ String tmp;
+ for (i = 0; i < bytes.length; i++) {
+ if (i > 0)
+ ret += ":";
+ tmp = Integer.toHexString(U8.f(bytes[i]));
+ if (tmp.length() == 1)
+ ret += "0";
+ ret += tmp;
+ }
+ return ret;
+ }
+
+ public static String toHexString(final long val, final int padTo) {
+ char arr[] = Long.toHexString(val).toCharArray();
+ String ret = "";
+ // prepend the right number of leading zeros
+ int i = 0;
+ for (; i < (padTo * 2 - arr.length); i++) {
+ ret += "0";
+ if ((i % 2) == 1)
+ ret += ":";
+ }
+ for (int j = 0; j < arr.length; j++) {
+ ret += arr[j];
+ if ((((i + j) % 2) == 1) && (j < (arr.length - 1)))
+ ret += ":";
+ }
+ return ret;
+ }
+
+ public static String toHexString(final long val) {
+ return toHexString(val, 8);
+ }
+
+ /**
+ * Convert a string of hex values into a string of bytes
+ *
+ * @param values
+ * "0f:ca:fe:de:ad:be:ef"
+ * @return [15, 5 ,2, 5, 17]
+ * @throws NumberFormatException
+ * If the string can not be parsed
+ */
+ public static byte[] fromHexString(final String values) throws NumberFormatException {
+ String[] octets = values.split(":");
+ byte[] ret = new byte[octets.length];
+
+ for (int i = 0; i < octets.length; i++) {
+ if (octets[i].length() > 2)
+ throw new NumberFormatException("Invalid octet length");
+ ret[i] = Integer.valueOf(octets[i], 16).byteValue();
+ }
+ return ret;
+ }
+
+ public static long toLong(final String values) throws NumberFormatException {
+ // Long.parseLong() can't handle HexStrings with MSB set. Sigh.
+ BigInteger bi = new BigInteger(values.replaceAll(":", ""), 16);
+ if (bi.bitLength() > 64)
+ throw new NumberFormatException("Input string too big to fit in long: "
+ + values);
+ return bi.longValue();
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/util/LRULinkedHashMap.java b/java_gen/pre-written/src/main/java/org/openflow/util/LRULinkedHashMap.java
new file mode 100644
index 0000000..216319d
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/util/LRULinkedHashMap.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.util;
+
+import java.util.LinkedHashMap;
+
+public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {
+ private static final long serialVersionUID = -2964986094089626647L;
+ protected int maximumCapacity;
+
+ public LRULinkedHashMap(final int initialCapacity, final int maximumCapacity) {
+ super(initialCapacity, 0.75f, true);
+ this.maximumCapacity = maximumCapacity;
+ }
+
+ public LRULinkedHashMap(final int maximumCapacity) {
+ super(16, 0.75f, true);
+ this.maximumCapacity = maximumCapacity;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(final java.util.Map.Entry<K, V> eldest) {
+ if (this.size() > maximumCapacity)
+ return true;
+ return false;
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/util/StringByteSerializer.java b/java_gen/pre-written/src/main/java/org/openflow/util/StringByteSerializer.java
new file mode 100644
index 0000000..72c1224
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/openflow/util/StringByteSerializer.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
+ * University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ **/
+
+package org.openflow.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+public class StringByteSerializer {
+ public static String readFrom(final ChannelBuffer data, final int length) {
+ byte[] stringBytes = new byte[length];
+ data.readBytes(stringBytes);
+ // find the first index of 0
+ int index = 0;
+ for (byte b : stringBytes) {
+ if (0 == b)
+ break;
+ ++index;
+ }
+ return new String(Arrays.copyOf(stringBytes, index), Charset.forName("ascii"));
+ }
+
+ public static void writeTo(final ChannelBuffer data, final int length,
+ final String value) {
+ try {
+ byte[] name = value.getBytes("ASCII");
+ if (name.length < length) {
+ data.writeBytes(name);
+ for (int i = name.length; i < length; ++i) {
+ data.writeByte((byte) 0);
+ }
+ } else {
+ data.writeBytes(name, 0, length - 1);
+ data.writeByte((byte) 0);
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+}
diff --git a/java_gen/pre-written/src/test/java/Test.java b/java_gen/pre-written/src/test/java/Test.java
new file mode 100644
index 0000000..e83700d
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/Test.java
@@ -0,0 +1,30 @@
+import org.openflow.protocol.match.MatchBuilderVer10;
+import org.openflow.types.MacAddress;
+import org.openflow.types.OFPort;
+
+
+public class Test {
+
+ private static volatile OFPort port;
+ private static volatile MacAddress ethSrc;
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ MacAddress mac = MacAddress.of("01:02:03:04:05:06");
+
+ long start = System.currentTimeMillis();
+ for(int i=0; i < 10000000; i++) {
+ MatchBuilderVer10 m = new MatchBuilderVer10();
+ // m.set(MatchField.IN_PORT, OFPort.CONTROLLER);
+ m.setInputPort(OFPort.CONTROLLER);
+ port = m.getInputPort(); //m.get(MatchField.IN_PORT);
+ m.setDataLayerSource(mac);
+ ethSrc = m.getDataLayerSource(); //(MatchField.ETH_SRC);
+ }
+ long end = System.currentTimeMillis();
+ System.out.println("end-start: "+ (end-start));
+ }
+
+}
diff --git a/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java b/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java
new file mode 100644
index 0000000..b19233c
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java
@@ -0,0 +1,89 @@
+package org.openflow.types;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortRead;
+
+public class IPv4Test {
+ byte[][] testAddresses = new byte[][] {
+ {0x01, 0x02, 0x03, 0x04 },
+ {127, 0, 0, 1},
+ {(byte) 192, (byte) 168, 0, 100 },
+ {(byte) 255, (byte) 255, (byte) 255, (byte) 255 }
+ };
+
+ String[] testStrings = {
+ "1.2.3.4",
+ "127.0.0.1",
+ "192.168.0.100",
+ "255.255.255.255"
+ };
+
+ int[] testInts = {
+ 0x01020304,
+ 0x7f000001,
+ (192 << 24) | (168 << 16) | 100,
+ 0xffffffff
+ };
+
+ String[] invalidIPs = {
+ "",
+ ".",
+ "1.2..3.4",
+ "1.2.3.4.",
+ "257.11.225.1",
+ "-1.2.3.4",
+ "1.2.3.4.5",
+ "1.x.3.4",
+ "1.2x.3.4"
+ };
+
+
+ @Test
+ public void testOfString() {
+ for(int i=0; i < testAddresses.length; i++ ) {
+ IPv4 ip = IPv4.of(testStrings[i]);
+ assertEquals(testInts[i], ip.getInt());
+ assertArrayEquals(testAddresses[i], ip.getBytes());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+ @Test
+ public void testOfByteArray() {
+ for(int i=0; i < testAddresses.length; i++ ) {
+ IPv4 ip = IPv4.of(testAddresses[i]);
+ assertEquals(testInts[i], ip.getInt());
+ assertArrayEquals(testAddresses[i], ip.getBytes());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+ @Test
+ public void testReadFrom() throws OFParseError, OFShortRead {
+ for(int i=0; i < testAddresses.length; i++ ) {
+ IPv4 ip = IPv4.readFrom(ChannelBuffers.copiedBuffer(testAddresses[i]));
+ assertEquals(testInts[i], ip.getInt());
+ assertArrayEquals(testAddresses[i], ip.getBytes());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+
+ @Test
+ public void testInvalidIPs() throws OFParseError, OFShortRead {
+ for(String invalid : invalidIPs) {
+ try {
+ IPv4.of(invalid);
+ fail("Invalid IP "+invalid+ " should have raised IllegalArgumentException");
+ } catch(IllegalArgumentException e) {
+ // ok
+ }
+ }
+ }
+}
diff --git a/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java b/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java
new file mode 100644
index 0000000..e3d5c81
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java
@@ -0,0 +1,88 @@
+package org.openflow.types;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortRead;
+
+public class IPv6Test {
+
+ String[] testStrings = {
+ "::",
+ "::1",
+ "ffe0::",
+ "1:2:3:4:5:6:7:8"
+ };
+
+ @Test
+ public void testOfString() throws UnknownHostException {
+ for(int i=0; i < testStrings.length; i++ ) {
+ IPv6 ip = IPv6.of(testStrings[i]);
+ InetAddress inetAddress = InetAddress.getByName(testStrings[i]);
+
+ assertArrayEquals(ip.getBytes(), inetAddress.getAddress());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+ @Test
+ public void testOfByteArray() throws UnknownHostException {
+ for(int i=0; i < testStrings.length; i++ ) {
+ byte[] bytes = Inet6Address.getByName(testStrings[i]).getAddress();
+ IPv6 ip = IPv6.of(bytes);
+ assertEquals(testStrings[i], ip.toString());
+ assertArrayEquals(bytes, ip.getBytes());
+ }
+ }
+
+ @Test
+ public void testReadFrom() throws OFParseError, OFShortRead, UnknownHostException {
+ for(int i=0; i < testStrings.length; i++ ) {
+ byte[] bytes = Inet6Address.getByName(testStrings[i]).getAddress();
+ IPv6 ip = IPv6.readFrom(ChannelBuffers.copiedBuffer(bytes));
+ assertEquals(testStrings[i], ip.toString());
+ assertArrayEquals(bytes, ip.getBytes());
+ }
+ }
+
+ String[] invalidIPs = {
+ "",
+ ":",
+ "1:2:3:4:5:6:7:8:9",
+ "1:2:3:4:5:6:7:8:",
+ "1:2:3:4:5:6:7:8g",
+ "1:2:3:",
+ "12345::",
+ "1::3::8",
+ "::3::"
+ };
+
+ @Test
+ public void testInvalidIPs() throws OFParseError, OFShortRead {
+ for(String invalid : invalidIPs) {
+ try {
+ IPv6.of(invalid);
+ fail("Invalid IP "+invalid+ " should have raised IllegalArgumentException");
+ } catch(IllegalArgumentException e) {
+ // ok
+ }
+ }
+ }
+
+ @Test
+ public void testZeroCompression() throws OFParseError, OFShortRead {
+ assertEquals("::", IPv6.of("::").toString(true, false));
+ assertEquals("0:0:0:0:0:0:0:0", IPv6.of("::").toString(false, false));
+ assertEquals("0000:0000:0000:0000:0000:0000:0000:0000", IPv6.of("::").toString(false, true));
+ assertEquals("1::4:5:6:0:8", IPv6.of("1:0:0:4:5:6:0:8").toString(true, false));
+ assertEquals("1:0:0:4::8", IPv6.of("1:0:0:4:0:0:0:8").toString(true, false));
+ }
+}
diff --git a/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java b/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java
new file mode 100644
index 0000000..af86d9b
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java
@@ -0,0 +1,86 @@
+package org.openflow.types;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.exceptions.OFShortRead;
+
+public class MacAddressTest {
+ byte[][] testAddresses = new byte[][] {
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
+ {(byte) 0x80, 0x0, 0x0, 0x0, 0x0, 0x01},
+ {(byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 }
+ };
+
+ String[] testStrings = {
+ "01:02:03:04:05:06",
+ "80:00:00:00:00:01",
+ "ff:ff:ff:ff:ff:ff"
+ };
+
+ long[] testInts = {
+ 0x00010203040506L,
+ 0x00800000000001L,
+ 0x00ffffffffffffL
+ };
+
+ String[] invalidMacs = {
+ "",
+ "1.2.3.4",
+ "00:ff:ef:12:12:ff:",
+ "00:fff:ef:12:12:ff",
+ "01:02:03:04:05;06",
+ "0:1:2:3:4:5:6",
+ "01:02:03:04"
+ };
+
+
+ @Test
+ public void testOfString() {
+ for(int i=0; i < testAddresses.length; i++ ) {
+ MacAddress ip = MacAddress.of(testStrings[i]);
+ assertEquals(testInts[i], ip.getLong());
+ assertArrayEquals(testAddresses[i], ip.getBytes());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+ @Test
+ public void testOfByteArray() {
+ for(int i=0; i < testAddresses.length; i++ ) {
+ MacAddress ip = MacAddress.of(testAddresses[i]);
+ assertEquals("error checking long representation of "+Arrays.toString(testAddresses[i]) + "(should be "+Long.toHexString(testInts[i]) +")", testInts[i], ip.getLong());
+ assertArrayEquals(testAddresses[i], ip.getBytes());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+ @Test
+ public void testReadFrom() throws OFParseError, OFShortRead {
+ for(int i=0; i < testAddresses.length; i++ ) {
+ MacAddress ip = MacAddress.readFrom(ChannelBuffers.copiedBuffer(testAddresses[i]));
+ assertEquals(testInts[i], ip.getLong());
+ assertArrayEquals(testAddresses[i], ip.getBytes());
+ assertEquals(testStrings[i], ip.toString());
+ }
+ }
+
+
+ @Test
+ public void testInvalidMacss() throws OFParseError, OFShortRead {
+ for(String invalid : invalidMacs) {
+ try {
+ MacAddress.of(invalid);
+ fail("Invalid IP "+invalid+ " should have raised IllegalArgumentException");
+ } catch(IllegalArgumentException e) {
+ // ok
+ }
+ }
+ }
+}
diff --git a/java_gen/templates/_autogen.java b/java_gen/templates/_autogen.java
new file mode 100644
index 0000000..e1ee006
--- /dev/null
+++ b/java_gen/templates/_autogen.java
@@ -0,0 +1,30 @@
+//:: # Copyright 2013, Big Switch Networks, Inc.
+//:: #
+//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+//:: # the following special exception:
+//:: #
+//:: # LOXI Exception
+//:: #
+//:: # As a special exception to the terms of the EPL, you may distribute libraries
+//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+//:: #
+//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//:: #
+//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+//:: # a copy of the EPL at:
+//:: #
+//:: # http://www.eclipse.org/legal/epl-v10.html
+//:: #
+//:: # Unless required by applicable law or agreed to in writing, software
+//:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+//:: # EPL for the specific language governing permissions and limitations
+//:: # under the EPL.
+//::
+//:: import inspect, os
+// Automatically generated by LOXI from template #{os.path.basename(inspect.stack()[3][1])}
+// Do not modify
diff --git a/java_gen/templates/_copyright.java b/java_gen/templates/_copyright.java
new file mode 100644
index 0000000..bf9ed02
--- /dev/null
+++ b/java_gen/templates/_copyright.java
@@ -0,0 +1,30 @@
+//:: # Copyright 2013, Big Switch Networks, Inc.
+//:: #
+//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+//:: # the following special exception:
+//:: #
+//:: # LOXI Exception
+//:: #
+//:: # As a special exception to the terms of the EPL, you may distribute libraries
+//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+//:: #
+//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//:: #
+//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+//:: # a copy of the EPL at:
+//:: #
+//:: # http://www.eclipse.org/legal/epl-v10.html
+//:: #
+//:: # Unless required by applicable law or agreed to in writing, software
+//:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+//:: # EPL for the specific language governing permissions and limitations
+//:: # under the EPL.
+//::
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+// Copyright (c) 2012, 2013 Big Switch Networks, Inc.
diff --git a/java_gen/templates/message_class.java b/java_gen/templates/message_class.java
new file mode 100644
index 0000000..2b4801c
--- /dev/null
+++ b/java_gen/templates/message_class.java
@@ -0,0 +1,258 @@
+//:: # Copyright 2013, Big Switch Networks, Inc.
+//:: #
+//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+//:: # the following special exception:
+//:: #
+//:: # LOXI Exception
+//:: #
+//:: # As a special exception to the terms of the EPL, you may distribute libraries
+//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+//:: #
+//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//:: #
+//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+//:: # a copy of the EPL at:
+//:: #
+//:: # http::: #www.eclipse.org/legal/epl-v10.html
+//:: #
+//:: # Unless required by applicable law or agreed to in writing, software
+//:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+//:: # EPL for the specific language governing permissions and limitations
+//:: # under the EPL.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package org.openflow.protocol;
+import java.util.Collections;
+import java.util.List;
+import org.openflow.protocol.actions.OFAction;
+import org.openflow.protocol.instructions.OFInstruction;
+import org.openflow.protocol.match.*;
+import org.openflow.types.*;
+import org.openflow.types.*;
+import org.openflow.util.*;
+import org.openflow.exceptions.*;
+import org.jboss.netty.buffer.ChannelBuffer;
+
+class ${impl_class} implements ${msg.interface_name} {
+//:: if msg.is_fixed_length(version):
+ private static final int LENGTH = ${msg.min_length(version) };
+//:: else:
+ private static final int MINIMUM_LENGTH = ${msg.min_length(version) };
+//:: #endif
+
+//:: for prop in msg.properties_for_version(version):
+ private final static ${prop.java_type.public_type} ${prop.default_name} = ${prop.default_value};
+//:: #end
+ private boolean xidSet;
+ private final int xid;
+
+ // OF message fields
+//:: for prop in msg.properties_for_version(version):
+ private final ${prop.java_type.public_type} ${prop.name};
+//:: #endfor
+
+ // Constructor
+ ${impl_class}(${
+ ", ".join(["int xid" ] + [ "%s %s" %(prop.java_type.public_type, prop.name) for prop in msg.properties_for_version(version) ])}) {
+ this.xidSet = true;
+ this.xid = xid;
+//:: for prop in msg.properties_for_version(version):
+ this.${prop.name} = ${prop.name};
+//:: #endfor
+ }
+
+ ${impl_class}(${
+ ", ".join("%s %s" %(prop.java_type.public_type, prop.name) for prop in msg.properties_for_version(version)) }) {
+ this.xidSet = false;
+ this.xid = 0;
+//:: for prop in msg.properties_for_version(version):
+ this.${prop.name} = ${prop.name};
+//:: #endfor
+ }
+
+ @Override
+ public int getXid() {
+ return xid;
+ }
+
+ @Override
+ public boolean isXidSet() {
+ return xidSet;
+ }
+
+ @Override
+ public OFType getType() {
+ return OFType.${msg.constant_name};
+ }
+
+ @Override
+ public OFVersion getVersion() {
+ return OFVersion.${version.constant_version};
+ }
+
+ // Accessors for OF message fields
+//:: for prop in msg.all_properties():
+ @Override
+ public ${prop.java_type.public_type} get${prop.title_name}()${ "" if msg.property_in_version(prop, version) else "throws UnsupportedOperationException"} {
+//:: if msg.property_in_version(prop, version):
+ return ${prop.name};
+//:: else:
+ throw new UnsupportedOperationException("Property ${prop.name} not supported in version #{version}");
+//:: #endif
+ }
+//:: #endfor
+
+ public ${msg.interface_name}.Builder createBuilder() {
+ return new BuilderImplWithParent(this);
+ }
+
+ static class BuilderImplWithParent implements ${msg.interface_name}.Builder {
+ final ${impl_class} parentMessage;
+ private boolean xidSet;
+ private int xid;
+
+ // OF message fields
+//:: for prop in msg.properties_for_version(version):
+ private boolean ${prop.name}Set;
+ private ${prop.java_type.public_type} ${prop.name};
+//:: #endfor
+
+ BuilderImplWithParent(${impl_class} parentMessage) {
+ this.parentMessage = parentMessage;
+ }
+
+//:: for prop in msg.all_properties():
+ @Override
+ public ${prop.java_type.public_type} get${prop.title_name}()${ "" if msg.property_in_version(prop, version) else " throws UnsupportedOperationException"} {
+//:: if msg.property_in_version(prop, version):
+ return ${prop.name};
+//:: else:
+ throw new UnsupportedOperationException("Property ${prop.name} not supported in version #{version}");
+//:: #endif
+ }
+ @Override
+ public ${msg.interface_name}.Builder set${prop.title_name}(${prop.java_type.public_type} ${prop.name})${ "" if msg.property_in_version(prop, version) else " throws UnsupportedOperationException"} {
+//:: if msg.property_in_version(prop, version):
+ this.${prop.name} = ${prop.name};
+ this.${prop.name}Set = true;
+ return this;
+//:: else:
+ throw new UnsupportedOperationException("Property ${prop.name} not supported in version #{version}");
+//:: #endif
+ }
+//:: #endfor
+ @Override
+ public ${msg.interface_name} getMessage() {
+ if(this.xidSet) {
+ return new ${impl_class}(
+ ${",\n ".join(
+ [ "xid" ] +
+ [ "this.{0}Set ? this.{0} : parentMessage.{0}".format(prop.name)
+ for prop in msg.properties_for_version(version)])}
+ );
+ } else {
+ return new ${impl_class}(
+ ${",\n ".join(
+ [ "this.{0}Set ? this.{0} : parentMessage.{0}".format(prop.name)
+ for prop in msg.properties_for_version(version)])}
+ );
+ }
+ }
+ }
+
+ static class BuilderImpl implements ${msg.interface_name}.Builder {
+ private boolean xidSet;
+ private int xid;
+
+ // OF message fields
+//:: for prop in msg.properties_for_version(version):
+ private boolean ${prop.name}Set;
+ private ${prop.java_type.public_type} ${prop.name};
+//:: #endfor
+
+//:: for prop in msg.all_properties():
+ @Override
+ public ${prop.java_type.public_type} get${prop.title_name}()${ "" if msg.property_in_version(prop, version) else " throws UnsupportedOperationException"} {
+//:: if msg.property_in_version(prop, version):
+ return ${prop.name};
+//:: else:
+ throw new UnsupportedOperationException("Property ${prop.name} not supported in version #{version}");
+//:: #endif
+ }
+ @Override
+ public ${msg.interface_name}.Builder set${prop.title_name}(${prop.java_type.public_type} ${prop.name})${ "" if msg.property_in_version(prop, version) else " throws UnsupportedOperationException"} {
+//:: if msg.property_in_version(prop, version):
+ this.${prop.name} = ${prop.name};
+ this.${prop.name}Set = true;
+ return this;
+//:: else:
+ throw new UnsupportedOperationException("Property ${prop.name} not supported in version #{version}");
+//:: #endif
+ }
+//:: #endfor
+ @Override
+ public ${msg.interface_name} getMessage() {
+ if(this.xidSet) {
+ return new ${impl_class}(
+ ${",\n ".join(
+ [ "xid" ] +
+ [ "this.{0}Set ? this.{0} : {1}.{2}".format(prop.name, impl_class, prop.default_name)
+ for prop in msg.properties_for_version(version)])}
+ );
+ } else {
+ return new ${impl_class}(
+ ${",\n ".join(
+ [ "this.{0}Set ? this.{0} : {1}.{2}".format(prop.name, impl_class, prop.default_name)
+ for prop in msg.properties_for_version(version)])}
+ );
+ }
+ }
+ }
+
+ final static Reader READER = new Reader();
+ static class Reader implements OFMessageReader<${msg.interface_name}> {
+ @Override
+ public ${msg.interface_name} readFrom(ChannelBuffer bb) throws OFParseError {
+ byte version = bb.readByte();
+ if (version != (byte) ${version.int_version})
+ throw new OFParseError("Wrong version: Expected=${version.int_version}, got="+version);
+
+ byte type = bb.readByte();
+ if(type != ${msg.wire_type(version)})
+ throw new OFParseError("Wrong message type: Expected=${msg.constant_name}, got="+type);
+
+ int length = bb.readUnsignedShort();
+//:: if msg.is_fixed_length(version):
+ if(length != LENGTH)
+ throw new OFParseError("Wrong message length: Expected="+LENGTH +", got="+length);
+//:: else:
+ if(length < MINIMUM_LENGTH)
+ throw new OFParseError("Insufficient message length: minimum length="+MINIMUM_LENGTH +", got="+length);
+//:: #endif
+ int xid = bb.readInt();
+//:: for prop in msg.properties_for_version(version, skip_pads=False):
+//:: if prop.is_pad:
+ // pad: ${prop.length} bytes
+ bb.skipBytes(${prop.length});
+//:: else:
+ ${prop.java_type.public_type} ${prop.name} = ${prop.java_type.read_op(version)};
+//:: #endif
+//:: #endfor
+ return new ${impl_class}(
+ ${",\n ".join(
+ [ "xid" ] + [ prop.name for prop in msg.properties_for_version(version)])}
+ );
+ }
+ }
+
+}
diff --git a/java_gen/templates/message_interface.java b/java_gen/templates/message_interface.java
new file mode 100644
index 0000000..904be95
--- /dev/null
+++ b/java_gen/templates/message_interface.java
@@ -0,0 +1,63 @@
+//:: # Copyright 2013, Big Switch Networks, Inc.
+//:: #
+//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+//:: # the following special exception:
+//:: #
+//:: # LOXI Exception
+//:: #
+//:: # As a special exception to the terms of the EPL, you may distribute libraries
+//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+//:: #
+//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//:: #
+//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+//:: # a copy of the EPL at:
+//:: #
+//:: # http::: #www.eclipse.org/legal/epl-v10.html
+//:: #
+//:: # Unless required by applicable law or agreed to in writing, software
+//:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+//:: # EPL for the specific language governing permissions and limitations
+//:: # under the EPL.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package org.openflow.protocol;
+import java.util.List;
+import org.openflow.protocol.match.*;
+import org.openflow.protocol.actions.OFAction;
+import org.openflow.protocol.instructions.OFInstruction;
+import org.openflow.types.*;
+import org.openflow.util.*;
+import org.openflow.exceptions.OFUnsupported;
+
+public interface ${msg.interface_name} extends OFMessage {
+ int getXid();
+ boolean isXidSet();
+ OFType getType();
+ OFVersion getVersion();
+
+//:: for prop in msg.all_properties():
+ ${prop.java_type.public_type} get${prop.title_name}()${ "" if prop.is_universal else "throws UnsupportedOperationException"};
+//:: #endfor
+
+ Builder createBuilder();
+
+ public interface Builder {
+ ${msg.interface_name} getMessage();
+//:: for prop in msg.all_properties():
+ ${prop.java_type.public_type} get${prop.title_name}()${ "" if prop.is_universal else "throws UnsupportedOperationException"};
+ Builder set${prop.title_name}(${prop.java_type.public_type} ${prop.name})${ "" if prop.is_universal else " throws UnsupportedOperationException"};
+//:: #endfor
+
+ }
+}
diff --git a/java_gen/templates/of_type.java b/java_gen/templates/of_type.java
new file mode 100644
index 0000000..951a648
--- /dev/null
+++ b/java_gen/templates/of_type.java
@@ -0,0 +1,51 @@
+//:: # Copyright 2013, Big Switch Networks, Inc.
+//:: #
+//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+//:: # the following special exception:
+//:: #
+//:: # LOXI Exception
+//:: #
+//:: # As a special exception to the terms of the EPL, you may distribute libraries
+//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+//:: #
+//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//:: #
+//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+//:: # a copy of the EPL at:
+//:: #
+//:: # http::: #www.eclipse.org/legal/epl-v10.html
+//:: #
+//:: # Unless required by applicable law or agreed to in writing, software
+//:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+//:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+//:: # EPL for the specific language governing permissions and limitations
+//:: # under the EPL.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package org.openflow.types;
+
+import org.openflow.protocol.OFVersion;
+
+public enum OFType {
+//:: for i, msg in enumerate(all_messages):
+ ${msg.constant_name}(new byte[] { ${ ", ".join( [str(msg.wire_type(version)) for version in all_versions ]) } } )${ ", " if i < len(all_messages)-1 else ";" }
+//:: #endfor
+
+ byte[] wireTypes;
+ OFType(byte[] wireTypes) {
+ this.wireTypes = wireTypes;
+ }
+
+ public byte getWireType(OFVersion version) {
+ return this.wireTypes[version.getWireVersion()];
+ }
+}
diff --git a/java_gen/test.sh b/java_gen/test.sh
new file mode 100755
index 0000000..7b71ffd
--- /dev/null
+++ b/java_gen/test.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+rm -rf target_code/
+cd ..
+./loxigen.py -ljava #&& ( cd target_code/Modules/openflowj/ && ant )