Merge remote-tracking branch 'upstream/master'
Conflicts:
c_gen/c_test_gen.py
java_gen/java_type.py
java_gen/pre-written/pom.xml
java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
loxi_ir/ir_offset.py
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 8726632..c8f70e6 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -184,14 +184,25 @@
@memoize
def enums(self):
name_version_enum_map = OrderedDefaultDict(lambda: OrderedDict())
+ name_stable_map = {}
for version in self.versions:
- logger.info("version: {}".format(version.ir_version))
+ logger.debug("version: {}".format(version.ir_version))
of_protocol = loxi_globals.ir[version.ir_version]
for enum in of_protocol.enums:
name_version_enum_map[enum.name][version] = enum
+ stable = (enum.params.get('stable') == 'True')
- enums = [ JavaEnum(name, version_enum_map) for name, version_enum_map,
+ logger.debug("Enum: %s stable: %s", enum.name, stable)
+
+ if not enum.name in name_stable_map:
+ name_stable_map[enum.name] = stable
+ else:
+ if name_stable_map[enum.name] != stable:
+ raise Exception("Inconsistent enum stability (should be caught " +\
+ " by IR)")
+
+ enums = [ JavaEnum(name, name_stable_map[name], version_enum_map) for name, version_enum_map,
in name_version_enum_map.items() ]
# inelegant - need java name here
@@ -402,6 +413,9 @@
reply_name = m.group(1) + "Reply"
if model.interface_by_name(reply_name):
return ["OFRequest<%s>" % reply_name ]
+ elif self.name == "OFBundleCtrlMsg":
+ reply_name = "OFBundleCtrlMsg"
+ return ["OFRequest<%s>" % reply_name ]
return []
@@ -573,6 +587,8 @@
if not find(lambda x: x.name == "mask", self.ir_model_members):
virtual_members.append(
JavaVirtualMember(self, "mask", find(lambda x: x.name == "value", self.ir_model_members).java_type))
+ elif self.name =="OFErrorMsg":
+ virtual_members += [ JavaVirtualMember(self, "data", java_type.error_cause_data) ]
if not find(lambda m: m.name == "version", self.ir_model_members):
virtual_members.append(JavaVirtualMember(self, "version", java_type.of_version))
@@ -815,7 +831,7 @@
entry = enum.entry_by_version_value(self.msg.version, self.value)
return "%s.%s" % ( enum.name, entry.name)
except KeyError, e:
- logger.debug("No enum found", e)
+ logger.debug("No enum found for type %s version %s value %s", java_type, self.msg.version, self.value)
return self.value
@property
@@ -1041,8 +1057,9 @@
#######################################################################
class JavaEnum(object):
- def __init__(self, c_name, version_enum_map):
+ def __init__(self, c_name, stable, version_enum_map):
self.c_name = c_name
+ self.stable = stable
self.name = "OF" + java_type.name_c_to_caps_camel("_".join(c_name.split("_")[1:]))
@@ -1062,7 +1079,23 @@
self.entries = [ e for e in self.entries if e.name not in model.enum_entry_blacklist[self.name] ]
self.package = "org.projectfloodlight.openflow.protocol"
- self.metadata = model.enum_metadata_map[self.name]
+ static_metadata = model.enum_metadata_map[self.name]
+ if self.stable:
+ # need this to look up wire_type, which does not matter
+ any_version = version_enum_map.keys()[0]
+ # if this is a 'stable' enum, i.e., its value won't change, add
+ # a "Metadata" (virtual) field "StableValue" to it that returns
+ # its wirevalue.
+ stable_value = JavaModel.OFEnumPropertyMetadata("StableValue",
+ self.wire_type(any_version),
+ value = lambda entry: entry.stable_value)
+
+ self.metadata = JavaModel.OFEnumMetadata(
+ properties=static_metadata.properties + (stable_value, ),
+ to_string=static_metadata.to_string
+ )
+ else:
+ self.metadata = static_metadata
def wire_type(self, version):
ir_enum = self.version_enums[version]
@@ -1113,7 +1146,7 @@
@property
def constructor_params(self):
- return [ m.value(self) for m in self.enum.metadata.properties ]
+ return [ (m.type, m.value(self)) for m in self.enum.metadata.properties ]
def has_value(self, version):
return version in self.values
@@ -1129,6 +1162,13 @@
return [ self.values[version] if version in self.values else not_present for version in versions ]
@property
+ def stable_value(self):
+ if self.enum.stable:
+ return self.values.values()[0]
+ else:
+ raise Exception("Enum {} not stable".format(self.enum.name))
+
+ @property
@memoize
def masked_enum_group(self):
group = find(lambda g: self.name in g.members, model.masked_enum_groups[self.enum.name])
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 5ff987d..900aa6d 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -53,9 +53,12 @@
signed-craziness
"""
signed, bits, cast_needed = java_primitives_info[t]
+ if t == 'boolean':
+ return "true" if bool(value) and value not in("False", "false") else "false"
+
max = (1 << bits)-1
if value > max:
- raise Exception("Value %d to large for type %s" % (value, t))
+ raise Exception("Value %s to large for type %s" % (value, t))
if signed:
max_pos = (1 << (bits-1)) - 1
@@ -361,10 +364,20 @@
.op(read="IPv4Address.read4Bytes(bb)", \
write="$name.write4Bytes(bb)",
default='IPv4Address.NONE')
+ipv4_list = JType('List<IPv4Address>') \
+ .op(read='ChannelUtils.readList(bb, $length, IPv4Address.READER)',
+ write='ChannelUtils.writeList(bb, $name)',
+ default='ImmutableList.<IPv4Address>of()',
+ funnel="FunnelUtils.putList($name, sink)")
ipv6 = JType("IPv6Address") \
.op(read="IPv6Address.read16Bytes(bb)", \
write="$name.write16Bytes(bb)",
default='IPv6Address.NONE')
+ipv6_list = JType('List<IPv46ddress>') \
+ .op(read='ChannelUtils.readList(bb, $length, IPv6Address.READER)',
+ write='ChannelUtils.writeList(bb, $name)',
+ default='ImmutableList.<IPv6Address>of()',
+ funnel="FunnelUtils.putList($name, sink)")
packetin_reason = gen_enum_jtype("OFPacketInReason")
transport_port = JType("TransportPort")\
.op(read="TransportPort.read2Bytes(bb)",
@@ -437,10 +450,14 @@
table_stats_wildcards = JType("int") \
.op(read='bb.readInt()',
write='bb.writeInt($name)')
-port_bitmap = JType('OFBitMask128') \
+port_bitmap_128 = JType('OFBitMask128') \
.op(read='OFBitMask128.read16Bytes(bb)',
write='$name.write16Bytes(bb)',
default='OFBitMask128.NONE')
+port_bitmap_512 = JType('OFBitMask512') \
+ .op(read='OFBitMask512.read64Bytes(bb)',
+ write='$name.write64Bytes(bb)',
+ default='OFBitMask512.NONE')
table_id = JType("TableId") \
.op(read='TableId.readByte(bb)',
write='$name.writeByte(bb)',
@@ -458,6 +475,10 @@
port_speed = JType("PortSpeed")
error_type = JType("OFErrorType")
+of_message = JType("OFMessage")\
+ .op(read="OFMessageVer$version.READER.readFrom(bb)",
+ write="$name.writeTo(bb)")
+
of_type = JType("OFType", 'byte') \
.op(read='bb.readByte()', write='bb.writeByte($name)')
action_type= gen_enum_jtype("OFActionType")\
@@ -505,6 +526,10 @@
.op(read='GenTableId.read2Bytes(bb)',
write='$name.write2Bytes(bb)',
)
+bundle_id = JType("BundleId") \
+ .op(read='BundleId.read4Bytes(bb)',
+ write='$name.write4Bytes(bb)',
+ )
udf = JType("UDF") \
.op(version=ANY, read="UDF.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="UDF.ZERO")
error_cause_data = JType("OFErrorCauseData") \
@@ -519,6 +544,10 @@
generic_t = JType("T")
+table_desc = JType('OFTableDesc') \
+ .op(read='OFTableDescVer$version.READER.readFrom(bb)', \
+ write='$name.writeTo(bb)')
+
default_mtype_to_jtype_convert_map = {
'uint8_t' : u8,
@@ -535,6 +564,8 @@
'list(of_uint32_t)' : u32_list,
'list(of_uint8_t)' : u8_list,
'list(of_oxm_t)' : oxm_list,
+ 'list(of_ipv4_t)' : ipv4_list,
+ 'list(of_ipv6_t)' : ipv6_list,
'of_octets_t' : octets,
'of_match_t': of_match,
'of_fm_cmd_t': flow_mod_cmd,
@@ -550,11 +581,13 @@
'of_wc_bmap_t': flow_wildcards,
'of_oxm_t': oxm,
'of_meter_features_t': meter_features,
- 'of_bitmap_128_t': port_bitmap,
+ 'of_bitmap_128_t': port_bitmap_128,
+ 'of_bitmap_512_t': port_bitmap_512,
'of_checksum_128_t': u128,
'of_bsn_vport_t': bsn_vport,
'of_app_code_t': app_code,
'of_sig_id_t': sig_id,
+ 'of_table_desc_t': table_desc,
}
## Map that defines exceptions from the standard loxi->java mapping scheme
@@ -608,9 +641,18 @@
'of_oxm_mpls_label_masked' : { 'value' : u32obj, 'value_mask' : u32obj },
'of_oxm_mpls_tc' : { 'value' : u8obj },
'of_oxm_mpls_tc_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
+ 'of_oxm_mpls_bos' : { 'value' : boolean_value },
+ 'of_oxm_mpls_bos_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
+ 'of_oxm_ipv6_exthdr' : { 'value' : u16obj },
+ 'of_oxm_ipv6_exthdr_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
+ 'of_oxm_pbb_uca' : { 'value' : boolean_value },
+ 'of_oxm_pbb_uca_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
- 'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap },
- 'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap, 'value_mask': port_bitmap },
+ 'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap_128 },
+ 'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap_128, 'value_mask': port_bitmap_128 },
+
+ 'of_oxm_bsn_in_ports_512' : { 'value': port_bitmap_512 },
+ 'of_oxm_bsn_in_ports_512_masked' : { 'value': port_bitmap_512, 'value_mask': port_bitmap_512 },
'of_oxm_bsn_lag_id' : { 'value' : lag_id },
'of_oxm_bsn_lag_id_masked' : { 'value' : lag_id, 'value_mask' : lag_id },
@@ -663,6 +705,9 @@
'of_oxm_bsn_vlan_xlate_port_group_id' : { 'value' : class_id },
'of_oxm_bsn_vlan_xlate_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
+ 'of_oxm_bsn_l2_cache_hit' : { 'value' : boolean_value },
+ 'of_oxm_bsn_l2_cache_hit_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
+
'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
@@ -704,8 +749,10 @@
'of_features_reply' : { 'auxiliary_id' : of_aux_id},
'of_oxm_och_sigtype' : { 'value' : u8obj },
'of_oxm_och_sigtype_basic' : { 'value' : u8obj },
- 'of_oxm_och_sigid' : {'value' : sig_id},
- 'of_oxm_och_sigid_basic' : {'value' : sig_id},
+ 'of_oxm_och_sigid' : {'value' : sig_id},
+ 'of_oxm_och_sigid_basic' : {'value' : sig_id},
+
+ 'of_bundle_add_msg' : { 'data' : of_message },
}
@@ -770,6 +817,8 @@
return action_type_set
elif field_name == "table_id" and re.match(r'of_bsn_gentable.*', obj_name):
return gen_table_id
+ elif field_name == "bundle_id" and re.match(r'of_bundle_.*', obj_name):
+ return bundle_id
elif c_type in default_mtype_to_jtype_convert_map:
return default_mtype_to_jtype_convert_map[c_type]
elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type):
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerator.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerator.java
new file mode 100644
index 0000000..2cb3583
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerator.java
@@ -0,0 +1,7 @@
+package org.projectfloodlight.openflow.protocol;
+
+import org.projectfloodlight.openflow.types.BundleId;
+
+public interface BundleIdGenerator {
+ BundleId nextBundleId();
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerators.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerators.java
new file mode 100644
index 0000000..997e0cd
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/BundleIdGenerators.java
@@ -0,0 +1,28 @@
+package org.projectfloodlight.openflow.protocol;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.projectfloodlight.openflow.types.BundleId;
+
+public class BundleIdGenerators {
+ private static final BundleIdGenerator GLOBAL_BUNDLE_ID_GENERATOR = create();
+
+ public static BundleIdGenerator create() {
+ return new StandardBundleIdGenerator();
+ }
+
+ public static BundleIdGenerator global() {
+ return GLOBAL_BUNDLE_ID_GENERATOR;
+ }
+}
+
+class StandardBundleIdGenerator implements BundleIdGenerator {
+
+ private final AtomicInteger idGen = new AtomicInteger();
+
+ @Override
+ public BundleId nextBundleId() {
+ return BundleId.of(idGen.incrementAndGet());
+ }
+
+}
\ No newline at end of file
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
index 6f54e5f..0c54fdc 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
@@ -1,7 +1,7 @@
package org.projectfloodlight.openflow.protocol;
public enum OFVersion {
- OF_10(1), OF_11(2), OF_12(3), OF_13(4);
+ OF_10(1), OF_11(2), OF_12(3), OF_13(4), OF_14(5);
public final int wireVersion;
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index 9fb3fd4..e2f172b 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -14,6 +14,7 @@
import org.projectfloodlight.openflow.types.LagId;
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.OFBitMask128;
+import org.projectfloodlight.openflow.types.OFBitMask512;
import org.projectfloodlight.openflow.types.OFBooleanValue;
import org.projectfloodlight.openflow.types.OFMetadata;
import org.projectfloodlight.openflow.types.OFPort;
@@ -179,12 +180,33 @@
new MatchField<U8>("mpls_tc", MatchFields.MPLS_TC,
new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.MPLS_UNICAST, EthType.MPLS_MULTICAST));
- public final static MatchField<U64> TUNNEL_ID =
+ public final static MatchField<OFBooleanValue> MPLS_BOS =
+ new MatchField<OFBooleanValue>("mpls_bos", MatchFields.MPLS_BOS,
+ new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.MPLS_UNICAST, EthType.MPLS_MULTICAST));
+
+ public final static MatchField<U64> TUNNEL_ID =
new MatchField<U64>("tunnel_id", MatchFields.TUNNEL_ID);
+ public final static MatchField<U16> IPV6_EXTHDR =
+ new MatchField<U16>("ipv6_exthdr", MatchFields.IPV6_EXTHDR);
+
+ public final static MatchField<OFBooleanValue> PBB_UCA =
+ new MatchField<OFBooleanValue>("pbb_uca", MatchFields.PBB_UCA);
+
+ public final static MatchField<IPv4Address> TUNNEL_IPV4_SRC =
+ new MatchField<IPv4Address>("tunnel_ipv4_src", MatchFields.TUNNEL_IPV4_SRC,
+ new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.IPv4));
+
+ public final static MatchField<IPv4Address> TUNNEL_IPV4_DST =
+ new MatchField<IPv4Address>("tunnel_ipv4_dst", MatchFields.TUNNEL_IPV4_DST,
+ new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.IPv4));
+
public final static MatchField<OFBitMask128> BSN_IN_PORTS_128 =
new MatchField<OFBitMask128>("bsn_in_ports_128", MatchFields.BSN_IN_PORTS_128);
+ public final static MatchField<OFBitMask512> BSN_IN_PORTS_512 =
+ new MatchField<OFBitMask512>("bsn_in_ports_512", MatchFields.BSN_IN_PORTS_512);
+
public final static MatchField<LagId> BSN_LAG_ID =
new MatchField<LagId>("bsn_lag_id", MatchFields.BSN_LAG_ID);
@@ -236,7 +258,6 @@
public final static MatchField<ClassId> BSN_VLAN_XLATE_PORT_GROUP_ID =
new MatchField<ClassId>("bsn_vlan_xlate_port_group_id", MatchFields.BSN_VLAN_XLATE_PORT_GROUP_ID);
-
public final static MatchField<U8> OCH_SIGTYPE =
new MatchField<U8>("och_sigtype",
MatchFields.OCH_SIGTYPE);
@@ -245,7 +266,6 @@
new MatchField<U8>("och_sigtype_basic",
MatchFields.OCH_SIGTYPE_BASIC);
-
public final static MatchField<CircuitSignalID> OCH_SIGID =
new MatchField<CircuitSignalID>("och_sigid",
MatchFields.OCH_SIGID);
@@ -254,6 +274,9 @@
new MatchField<CircuitSignalID>("och_sigid_basic",
MatchFields.OCH_SIGID);
+ public final static MatchField<OFBooleanValue> BSN_L2_CACHE_HIT =
+ new MatchField<OFBooleanValue>("bsn_l2_cache_hit", MatchFields.BSN_L2_CACHE_HIT);
+
public String getName() {
return name;
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
index 3bf717b..12e2b20 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
@@ -38,8 +38,14 @@
IPV6_ND_TLL,
MPLS_LABEL,
MPLS_TC,
+ MPLS_BOS,
TUNNEL_ID,
+ IPV6_EXTHDR,
+ PBB_UCA,
+ TUNNEL_IPV4_SRC,
+ TUNNEL_IPV4_DST,
BSN_IN_PORTS_128,
+ BSN_IN_PORTS_512,
BSN_LAG_ID,
BSN_VRF,
BSN_GLOBAL_VRF_ALLOWED,
@@ -57,8 +63,9 @@
BSN_UDF7,
BSN_TCP_FLAGS,
BSN_VLAN_XLATE_PORT_GROUP_ID,
+ BSN_L2_CACHE_HIT,
OCH_SIGTYPE,
OCH_SIGTYPE_BASIC,
OCH_SIGID,
- OCH_SIGID_BASIC,;
+ OCH_SIGID_BASIC,
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
new file mode 100644
index 0000000..c893cab
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
@@ -0,0 +1,26 @@
+package org.projectfloodlight.openflow.protocol.ver14;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.projectfloodlight.openflow.protocol.OFMatchBmap;
+import org.projectfloodlight.openflow.protocol.match.Match;
+
+/**
+ * Collection of helper functions for reading and writing into ChannelBuffers
+ *
+ * @author capveg
+ */
+
+public class ChannelUtilsVer14 {
+ public static Match readOFMatch(final ChannelBuffer bb) throws OFParseError {
+ return OFMatchV3Ver14.READER.readFrom(bb);
+ }
+
+ public static OFMatchBmap readOFMatchBmap(ChannelBuffer bb) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public static void writeOFMatchBmap(ChannelBuffer bb, OFMatchBmap match) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/BundleId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/BundleId.java
new file mode 100644
index 0000000..cccf67e
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/BundleId.java
@@ -0,0 +1,92 @@
+package org.projectfloodlight.openflow.types;
+
+import javax.annotation.concurrent.Immutable;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+import com.google.common.hash.PrimitiveSink;
+import com.google.common.primitives.UnsignedInts;
+
+@Immutable
+public class BundleId implements OFValueType<BundleId> {
+ static final int LENGTH = 4;
+
+ private final static int NONE_VAL = 0;
+ public final static BundleId NONE = new BundleId(NONE_VAL);
+
+ private final static int NO_MASK_VAL = 0xFFFFFFFF;
+ public final static BundleId NO_MASK = new BundleId(NO_MASK_VAL);
+ public final static BundleId FULL_MASK = NONE;
+
+ private final int rawValue;
+
+ private BundleId(final int rawValue) {
+ this.rawValue = rawValue;
+ }
+
+ public static BundleId of(final int raw) {
+ if(raw == NONE_VAL)
+ return NONE;
+ else if(raw == NO_MASK_VAL)
+ return NO_MASK;
+ return new BundleId(raw);
+ }
+
+ public int getInt() {
+ return rawValue;
+ }
+
+ @Override
+ public int getLength() {
+ return LENGTH;
+ }
+
+ @Override
+ public String toString() {
+ return UnsignedInts.toString(rawValue);
+ }
+
+ @Override
+ public BundleId applyMask(BundleId mask) {
+ return BundleId.of(rawValue & mask.rawValue); }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + rawValue;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BundleId other = (BundleId) obj;
+ if (rawValue != other.rawValue)
+ return false;
+ return true;
+ }
+
+ public void write4Bytes(ChannelBuffer c) {
+ c.writeInt(rawValue);
+ }
+
+ public static BundleId read4Bytes(ChannelBuffer c) {
+ return BundleId.of(c.readInt());
+ }
+
+ @Override
+ public int compareTo(BundleId o) {
+ return UnsignedInts.compare(rawValue, rawValue);
+ }
+
+ @Override
+ public void putTo(PrimitiveSink sink) {
+ sink.putInt(rawValue);
+ }
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java
index 7d7c38e..98c1253 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/ClassId.java
@@ -43,7 +43,7 @@
@Override
public String toString() {
- return Integer.toString(rawValue);
+ return UnsignedInts.toString(rawValue);
}
@Override
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
index 3a1b15e..eb37a20 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
@@ -12,14 +12,16 @@
import com.google.common.hash.PrimitiveSink;
import com.google.common.primitives.UnsignedInts;
-
+import org.projectfloodlight.openflow.protocol.Writeable;
+import org.projectfloodlight.openflow.protocol.OFMessageReader;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
/**
* Wrapper around an IPv4Address address
*
* @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
*/
-public class IPv4Address extends IPAddress<IPv4Address> {
+public class IPv4Address extends IPAddress<IPv4Address> implements Writeable {
static final int LENGTH = 4;
private final int rawValue;
@@ -38,6 +40,15 @@
this.rawValue = rawValue;
}
+ public final static Reader READER = new Reader();
+
+ private static class Reader implements OFMessageReader<IPv4Address> {
+ @Override
+ public IPv4Address readFrom(ChannelBuffer bb) throws OFParseError {
+ return new IPv4Address(bb.readInt());
+ }
+ }
+
@Override
public IPVersion getIpVersion() {
return IPVersion.IPv4;
@@ -345,4 +356,8 @@
sink.putInt(rawValue);
}
+ @Override
+ public void writeTo(ChannelBuffer bb) {
+ bb.writeInt(rawValue);
+ }
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
index 471d0fb..9d6fa4d 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
@@ -8,19 +8,22 @@
import javax.annotation.Nonnull;
import org.jboss.netty.buffer.ChannelBuffer;
-import org.projectfloodlight.openflow.exceptions.OFParseError;
import com.google.common.base.Preconditions;
import com.google.common.hash.PrimitiveSink;
import com.google.common.primitives.Longs;
+import org.projectfloodlight.openflow.protocol.Writeable;
+import org.projectfloodlight.openflow.protocol.OFMessageReader;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+
/**
* 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 IPv6Address extends IPAddress<IPv6Address> {
+public class IPv6Address extends IPAddress<IPv6Address> implements Writeable {
static final int LENGTH = 16;
private final long raw1;
private final long raw2;
@@ -43,6 +46,15 @@
this.raw2 = raw2;
}
+ public final static Reader READER = new Reader();
+
+ private static class Reader implements OFMessageReader<IPv6Address> {
+ @Override
+ public IPv6Address readFrom(ChannelBuffer bb) throws OFParseError {
+ return new IPv6Address(bb.readLong(), bb.readLong());
+ }
+ }
+
@Override
public IPVersion getIpVersion() {
return IPVersion.IPv6;
@@ -213,8 +225,17 @@
public static IPv6Address of(@Nonnull final String string) throws IllegalArgumentException {
Preconditions.checkNotNull(string, "string must not be null");
+ // remove the zone id
+ int zoneDelimIndex = string.indexOf("%");
+ String substring;
+ if (zoneDelimIndex != -1) {
+ substring = string.substring(0, zoneDelimIndex);
+ } else {
+ substring = string;
+ }
+
IPv6Builder builder = new IPv6Builder();
- String[] parts = colonPattern.split(string, -1);
+ String[] parts = colonPattern.split(substring, -1);
int leftWord = 0;
int leftIndex = 0;
@@ -538,4 +559,10 @@
sink.putLong(raw1);
sink.putLong(raw2);
}
+
+ @Override
+ public void writeTo(ChannelBuffer bb) {
+ bb.writeLong(raw1);
+ bb.writeLong(raw2);
+ }
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
new file mode 100644
index 0000000..3fe9b88
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBitMask512.java
@@ -0,0 +1,205 @@
+package org.projectfloodlight.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+import com.google.common.hash.PrimitiveSink;
+
+public class OFBitMask512 implements OFValueType<OFBitMask512> {
+
+ static final int LENGTH = 64;
+
+ private final long raw1;
+ private final long raw2;
+ private final long raw3;
+ private final long raw4;
+ private final long raw5;
+ private final long raw6;
+ private final long raw7;
+ private final long raw8;
+
+ public static final OFBitMask512 ALL = new OFBitMask512(-1, -1, -1, -1,
+ -1, -1, -1, -1);
+ public static final OFBitMask512 NONE = new OFBitMask512(0, 0, 0, 0,
+ 0, 0, 0, 0);
+
+ public static final OFBitMask512 NO_MASK = ALL;
+ public static final OFBitMask512 FULL_MASK = NONE;
+
+ private OFBitMask512(long raw1, long raw2, long raw3, long raw4,
+ long raw5, long raw6, long raw7, long raw8) {
+ this.raw1 = raw1;
+ this.raw2 = raw2;
+ this.raw3 = raw3;
+ this.raw4 = raw4;
+ this.raw5 = raw5;
+ this.raw6 = raw6;
+ this.raw7 = raw7;
+ this.raw8 = raw8;
+ }
+
+ public static OFBitMask512 of(long raw1, long raw2, long raw3, long raw4,
+ long raw5, long raw6, long raw7, long raw8) {
+ if (raw1 == -1 && raw2 == -1 && raw3 == -1 && raw4 == -1
+ && raw5 == -1 && raw6 == -1 && raw7 == -1 && raw8 == -1)
+ return ALL;
+ if (raw1 == 0 && raw2 == 0 && raw3 == 0 && raw4 == 0
+ && raw5 == 0 && raw6 == 0 && raw7 == 0 && raw8 == 0)
+ return NONE;
+ return new OFBitMask512(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8);
+ }
+
+ @Override
+ public int getLength() {
+ return LENGTH;
+ }
+
+ @Override
+ public OFBitMask512 applyMask(OFBitMask512 mask) {
+ return of(this.raw1 & mask.raw1, this.raw2 & mask.raw2,
+ this.raw3 & mask.raw3, this.raw4 & mask.raw4,
+ this.raw5 & mask.raw5, this.raw6 & mask.raw6,
+ this.raw7 & mask.raw7, this.raw8 & mask.raw8);
+ }
+
+ @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));
+ result = prime * result + (int) (raw3 ^ (raw3 >>> 32));
+ result = prime * result + (int) (raw4 ^ (raw4 >>> 32));
+ result = prime * result + (int) (raw5 ^ (raw5 >>> 32));
+ result = prime * result + (int) (raw6 ^ (raw6 >>> 32));
+ result = prime * result + (int) (raw7 ^ (raw7 >>> 32));
+ result = prime * result + (int) (raw8 ^ (raw8 >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ OFBitMask512 other = (OFBitMask512) obj;
+ if (raw1 != other.raw1) return false;
+ if (raw2 != other.raw2) return false;
+ if (raw3 != other.raw3) return false;
+ if (raw4 != other.raw4) return false;
+ if (raw5 != other.raw5) return false;
+ if (raw6 != other.raw6) return false;
+ if (raw7 != other.raw7) return false;
+ if (raw8 != other.raw8) return false;
+ return true;
+ }
+
+ protected static boolean isBitOn(long raw1, long raw2, long raw3, long raw4,
+ long raw5, long raw6, long raw7, long raw8, int bit) {
+ if (bit < 0 || bit >= 512)
+ throw new IndexOutOfBoundsException();
+ long word;
+ if (bit < 64) {
+ word = raw8;
+ } else if (bit < 128) {
+ word = raw7;
+ bit -= 64;
+ } else if (bit < 128) {
+ word = raw6;
+ bit -= 128;
+ } else if (bit < 128) {
+ word = raw5;
+ bit -= 192;
+ } else if (bit < 128) {
+ word = raw4;
+ bit -= 256;
+ } else if (bit < 128) {
+ word = raw3;
+ bit -= 320;
+ } else if (bit < 128) {
+ word = raw2;
+ bit -= 384;
+ } else {
+ word = raw1;
+ bit -= 448;
+ }
+ return (word & ((long)1 << bit)) != 0;
+ }
+
+ public void write64Bytes(ChannelBuffer cb) {
+ cb.writeLong(raw1);
+ cb.writeLong(raw2);
+ cb.writeLong(raw3);
+ cb.writeLong(raw4);
+ cb.writeLong(raw5);
+ cb.writeLong(raw6);
+ cb.writeLong(raw7);
+ cb.writeLong(raw8);
+ }
+
+ public static OFBitMask512 read64Bytes(ChannelBuffer cb) {
+ long raw1 = cb.readLong();
+ long raw2 = cb.readLong();
+ long raw3 = cb.readLong();
+ long raw4 = cb.readLong();
+ long raw5 = cb.readLong();
+ long raw6 = cb.readLong();
+ long raw7 = cb.readLong();
+ long raw8 = cb.readLong();
+ return of(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8);
+ }
+
+ public boolean isOn(int bit) {
+ return isBitOn(raw1, raw2, raw3, raw4, raw5, raw6, raw7, raw8, bit);
+ }
+
+ @Override
+ public String toString() {
+ return (String.format("%64s", Long.toBinaryString(raw8))
+ + String.format("%64s", Long.toBinaryString(raw7))
+ + String.format("%64s", Long.toBinaryString(raw6))
+ + String.format("%64s", Long.toBinaryString(raw5))
+ + String.format("%64s", Long.toBinaryString(raw4))
+ + String.format("%64s", Long.toBinaryString(raw3))
+ + String.format("%64s", Long.toBinaryString(raw2))
+ + String.format("%64s", Long.toBinaryString(raw1))).replaceAll(" ", "0");
+ }
+
+ @Override
+ public int compareTo(OFBitMask512 o) {
+ long c = this.raw1 - o.raw1;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw2 - o.raw2;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw3 - o.raw3;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw4 - o.raw4;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw5 - o.raw5;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw6 - o.raw6;
+ if (c != 0)
+ return Long.signum(c);
+ c = this.raw7 - o.raw7;
+ if (c != 0)
+ return Long.signum(c);
+ return Long.signum(this.raw8 - o.raw8);
+ }
+
+ @Override
+ public void putTo(PrimitiveSink sink) {
+ sink.putLong(raw1);
+ sink.putLong(raw2);
+ sink.putLong(raw3);
+ sink.putLong(raw4);
+ sink.putLong(raw5);
+ sink.putLong(raw6);
+ sink.putLong(raw7);
+ sink.putLong(raw8);
+ }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
index a919f62..3ee588f 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
@@ -22,10 +22,10 @@
* reasons in Match.MetaData field.
* */
public static Set<OFBsnPktinFlag> getOFBsnPktinFlags(OFPacketIn pktIn) {
- if(pktIn.getVersion() != OFVersion.OF_13) {
+ if(pktIn.getVersion().compareTo(OFVersion.OF_13) < 0) {
throw new IllegalArgumentException("multiple pkt in reasons are "
+ "only supported by BVS using "
- + "openflow 1.3");
+ + "openflow version >= 1.3");
}
Match match = pktIn.getMatch();
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
index a397c2a..fd26856 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
@@ -399,4 +399,10 @@
assertNotNull(e.getMessage());
}
}
+
+ @Test
+ public void testZoneId() throws OFParseError {
+ assertEquals("::", IPv6Address.of("::%eth0").toString(true, false));
+ assertEquals("1:0:0:4::8", IPv6Address.of("1:0:0:4:0:0:0:8%2").toString(true, false));
+ }
}
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
new file mode 100644
index 0000000..965e314
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
@@ -0,0 +1,53 @@
+package org.projectfloodlight.protocol;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.junit.Test;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPortConfig;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortState;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+
+import static org.hamcrest.Matchers.is;
+
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests auxiliary OFPortDesc methods for all versions of OpenFlow
+ *
+ * @author Jason Parraga <jason.parraga@bigswitch.com>
+ */
+public class OFPortDescTest {
+
+ @Test
+ public void testIsEnabled() {
+ testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_10));
+ testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_11));
+ testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_12));
+ testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_13));
+ testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_14));
+ }
+
+ public void testIsEnabledForFactory(OFFactory factory) {
+ // Default
+ OFPortDesc desc = factory.buildPortDesc()
+ .build();
+ assertThat(desc.isEnabled(), is(true));
+
+ // Partially disabled
+ desc = factory.buildPortDesc()
+ .setConfig(new HashSet<OFPortConfig>(Arrays.asList(OFPortConfig.PORT_DOWN)))
+ .build();
+ assertThat(desc.isEnabled(), is(false));
+
+ // Fully disabled
+ desc = factory.buildPortDesc()
+ .setConfig(new HashSet<OFPortConfig>(Arrays.asList(OFPortConfig.PORT_DOWN)))
+ .setState(new HashSet<OFPortState>(Arrays.asList(OFPortState.LINK_DOWN)))
+ .build();
+ assertThat(desc.isEnabled(), is(false));
+ }
+}
diff --git a/java_gen/templates/const.java b/java_gen/templates/const.java
index a7786f4..1828bac 100644
--- a/java_gen/templates/const.java
+++ b/java_gen/templates/const.java
@@ -37,7 +37,7 @@
public enum ${class_name} {
//:: for i, entry in enumerate(enum.entries):
//:: if enum.metadata.properties:
-//:: params = "({})".format(", ".join(entry.constructor_params))
+//:: params = "({})".format(", ".join(type.format_value(value) for (type, value) in entry.constructor_params))
//:: else:
//:: params = ""
//:: #endif
diff --git a/java_gen/templates/custom/OFMatchV3.Builder.java b/java_gen/templates/custom/OFMatchV3.Builder.java
new file mode 100644
index 0000000..54b35ba
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3.Builder.java
@@ -0,0 +1,106 @@
+
+ private OFOxmList.Builder oxmListBuilder;
+
+ private void initBuilder() {
+ if (oxmListBuilder != null)
+ return;
+ oxmListBuilder = new OFOxmList.Builder();
+ }
+
+ private void updateOxmList() {
+ this.oxmList = this.oxmListBuilder.build();
+ this.oxmListSet = true;
+ }
+
+ private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
+//:: if has_parent:
+ return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
+//:: else:
+ return this.oxmListSet ? this.oxmList.get(field) : null;
+//:: #endif
+ }
+
+ @Override
+ public <F extends OFValueType<F>> F get(MatchField<F> field)
+ throws UnsupportedOperationException {
+ OFOxm<F> value = getOxm(field);
+ if (value == null)
+ return null;
+ return value.getValue();
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
+ throws UnsupportedOperationException {
+ OFOxm<F> value = getOxm(field);
+ if (value == null || !value.isMasked())
+ return null;
+ // TODO: If changing OXMs to extend Masked, then use it here
+ return Masked.of(value.getValue(), value.getMask());
+ }
+
+ @Override
+ public boolean supports(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean supportsMasked(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean isExact(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value != null && !value.isMasked());
+ }
+
+ @Override
+ public boolean isFullyWildcarded(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value == null);
+ }
+
+ @Override
+ public boolean isPartiallyMasked(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value != null && value.isMasked());
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setExact(
+ MatchField<F> field, F value) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromValue(value, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setMasked(
+ MatchField<F> field, F value, F mask) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromValueAndMask(value, mask, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setMasked(
+ MatchField<F> field, Masked<F> valueWithMask) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromMasked(valueWithMask, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
+ initBuilder();
+ this.oxmListBuilder.unset(field);
+ updateOxmList();
+ return this;
+ }
diff --git a/java_gen/templates/custom/OFMatchV3.java b/java_gen/templates/custom/OFMatchV3.java
new file mode 100644
index 0000000..799135c
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3.java
@@ -0,0 +1,112 @@
+//:: from generic_utils import OrderedSet
+//:: from java_gen.java_model import model
+ @Override
+ public <F extends OFValueType<F>> F get(MatchField<F> field)
+ throws UnsupportedOperationException {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<F> oxm = this.oxmList.get(field);
+
+ if (oxm == null || !field.arePrerequisitesOK(this))
+ return null;
+
+ return oxm.getValue();
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
+ throws UnsupportedOperationException {
+ if (!supportsMasked(field))
+ throw new UnsupportedOperationException("${msg.name} does not support masked matching on field " + field.getName());
+
+ OFOxm<F> oxm = this.oxmList.get(field);
+
+ if (oxm == null || !field.arePrerequisitesOK(this))
+ return null;
+
+ if (oxm.getMask() == null)
+ return null;
+
+ // TODO: Make OfOxm extend Masked and just return the OXM?
+ return Masked.of(oxm.getValue(), oxm.getMask());
+ }
+
+ private static boolean supportsField(MatchField<?> field) {
+ switch (field.id) {
+ //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
+ case ${id_constant}:
+ //:: #endfor
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean supports(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean supportsMasked(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean isExact(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm != null && !oxm.isMasked();
+ }
+
+ @Override
+ public boolean isFullyWildcarded(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm == null;
+ }
+
+ @Override
+ public boolean isPartiallyMasked(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm != null && oxm.isMasked();
+ }
+
+ private class MatchFieldIterator extends AbstractIterator<MatchField<?>> {
+ private Iterator<OFOxm<?>> oxmIterator;
+
+ MatchFieldIterator() {
+ oxmIterator = oxmList.iterator();
+ }
+
+ @Override
+ protected MatchField<?> computeNext() {
+ while(oxmIterator.hasNext()) {
+ OFOxm<?> oxm = oxmIterator.next();
+ if(oxm.getMatchField().arePrerequisitesOK(${msg.name}.this))
+ return oxm.getMatchField();
+ }
+ endOfData();
+ return null;
+ }
+ }
+
+ @Override
+ public Iterable<MatchField<?>> getMatchFields() {
+ return new Iterable<MatchField<?>>() {
+ public Iterator<MatchField<?>> iterator() {
+ return new MatchFieldIterator();
+ }
+ };
+ }
diff --git a/java_gen/templates/custom/OFMatchV3Ver12.Builder.java b/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
index 3fae367..ae2ecaa 100644
--- a/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
+++ b/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
@@ -1,106 +1 @@
-
- private OFOxmList.Builder oxmListBuilder;
-
- private synchronized void initBuilder() {
- if (oxmListBuilder != null)
- return;
- oxmListBuilder = new OFOxmList.Builder();
- }
-
- private synchronized void updateOxmList() {
- this.oxmList = this.oxmListBuilder.build();
- this.oxmListSet = true;
- }
-
- private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
-//:: if has_parent:
- return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
-//:: else:
- return this.oxmListSet ? this.oxmList.get(field) : null;
-//:: #endif
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null)
- return null;
- return value.getValue();
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null || !value.isMasked())
- return null;
- // TODO: If changing OXMs to extend Masked, then use it here
- return Masked.of(value.getValue(), value.getMask());
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public synchronized boolean isExact(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && !value.isMasked());
- }
-
- @Override
- public synchronized boolean isFullyWildcarded(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value == null);
- }
-
- @Override
- public synchronized boolean isPartiallyMasked(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && value.isMasked());
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setExact(
- MatchField<F> field, F value) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValue(value, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, F value, F mask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValueAndMask(value, mask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, Masked<F> valueWithMask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromMasked(valueWithMask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
- initBuilder();
- this.oxmListBuilder.unset(field);
- updateOxmList();
- return this;
- }
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver12.java b/java_gen/templates/custom/OFMatchV3Ver12.java
index 81092c1..225b0dc 100644
--- a/java_gen/templates/custom/OFMatchV3Ver12.java
+++ b/java_gen/templates/custom/OFMatchV3Ver12.java
@@ -1,114 +1 @@
-
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- return oxm.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supportsMasked(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support masked matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- if (oxm.getMask() == null)
- return null;
-
- // TODO: Make OfOxm extend Masked and just return the OXM?
- return Masked.of(oxm.getValue(), oxm.getMask());
- }
-
- private static boolean supportsField(MatchField<?> field) {
- switch (field.id) {
- case IN_PORT:
- case IN_PHY_PORT:
- case METADATA:
- case ETH_DST:
- case ETH_SRC:
- case ETH_TYPE:
- case VLAN_VID:
- case VLAN_PCP:
- case IP_DSCP:
- case IP_ECN:
- case IP_PROTO:
- case IPV4_SRC:
- case IPV4_DST:
- case TCP_SRC:
- case TCP_DST:
- case UDP_SRC:
- case UDP_DST:
- case SCTP_SRC:
- case SCTP_DST:
- case ICMPV4_TYPE:
- case ICMPV4_CODE:
- case ARP_OP:
- case ARP_SPA:
- case ARP_TPA:
- case ARP_SHA:
- case ARP_THA:
- case IPV6_SRC:
- case IPV6_DST:
- case IPV6_FLABEL:
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && !oxm.isMasked();
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm == null;
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && oxm.isMasked();
- }
-
- @Override
- public Iterable<MatchField<?>> getMatchFields() {
- throw new UnsupportedOperationException();
- }
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver12_toString.java b/java_gen/templates/custom/OFMatchV3Ver12_toString.java
new file mode 100644
index 0000000..3b2783b
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver12_toString.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatch_toString.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.Builder.java b/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
index 79cbdbc..ae2ecaa 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
@@ -1,107 +1 @@
-
- private OFOxmList.Builder oxmListBuilder;
-
- private void initBuilder() {
- if (oxmListBuilder != null)
- return;
- oxmListBuilder = new OFOxmList.Builder();
- }
-
- private void updateOxmList() {
- this.oxmList = this.oxmListBuilder.build();
- this.oxmListSet = true;
- }
-
- private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
-//:: if has_parent:
- return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
-//:: else:
- return this.oxmListSet ? this.oxmList.get(field) : null;
-//:: #endif
- }
-
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null)
- return null;
- return value.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null || !value.isMasked())
- return null;
- // TODO: If changing OXMs to extend Masked, then use it here
- return Masked.of(value.getValue(), value.getMask());
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && !value.isMasked());
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value == null);
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && value.isMasked());
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setExact(
- MatchField<F> field, F value) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValue(value, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, F value, F mask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValueAndMask(value, mask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, Masked<F> valueWithMask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromMasked(valueWithMask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
- initBuilder();
- this.oxmListBuilder.unset(field);
- updateOxmList();
- return this;
- }
-
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.java b/java_gen/templates/custom/OFMatchV3Ver13.java
index dc8e637..225b0dc 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.java
@@ -1,112 +1 @@
-//:: from generic_utils import OrderedSet
-//:: from java_gen.java_model import model
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- return oxm.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supportsMasked(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support masked matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- if (oxm.getMask() == null)
- return null;
-
- // TODO: Make OfOxm extend Masked and just return the OXM?
- return Masked.of(oxm.getValue(), oxm.getMask());
- }
-
- private static boolean supportsField(MatchField<?> field) {
- switch (field.id) {
- //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
- case ${id_constant}:
- //:: #endfor
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && !oxm.isMasked();
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm == null;
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && oxm.isMasked();
- }
-
- private class MatchFieldIterator extends AbstractIterator<MatchField<?>> {
- private Iterator<OFOxm<?>> oxmIterator;
-
- MatchFieldIterator() {
- oxmIterator = oxmList.iterator();
- }
-
- @Override
- protected MatchField<?> computeNext() {
- while(oxmIterator.hasNext()) {
- OFOxm<?> oxm = oxmIterator.next();
- if(oxm.getMatchField().arePrerequisitesOK(OFMatchV3Ver13.this))
- return oxm.getMatchField();
- }
- endOfData();
- return null;
- }
- }
-
- @Override
- public Iterable<MatchField<?>> getMatchFields() {
- return new Iterable<MatchField<?>>() {
- public Iterator<MatchField<?>> iterator() {
- return new MatchFieldIterator();
- }
- };
- }
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14.Builder.java b/java_gen/templates/custom/OFMatchV3Ver14.Builder.java
new file mode 100644
index 0000000..ae2ecaa
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14.Builder.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14.java b/java_gen/templates/custom/OFMatchV3Ver14.java
new file mode 100644
index 0000000..225b0dc
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14_toString.java b/java_gen/templates/custom/OFMatchV3Ver14_toString.java
new file mode 100644
index 0000000..3b2783b
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14_toString.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatch_toString.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFPortDesc.java b/java_gen/templates/custom/OFPortDesc.java
new file mode 100644
index 0000000..3be1b70
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDesc.java
@@ -0,0 +1,11 @@
+
+ /**
+ * Returns true if the port is up, i.e., it's neither administratively
+ * down nor link down. It currently does NOT take STP state into
+ * consideration
+ * @return whether the port is up
+ */
+ public boolean isEnabled() {
+ return (!state.contains(OFPortState.LINK_DOWN) && !config.contains(OFPortConfig.PORT_DOWN));
+ }
+
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer10.java b/java_gen/templates/custom/OFPortDescVer10.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer10.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer11.java b/java_gen/templates/custom/OFPortDescVer11.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer11.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer12.java b/java_gen/templates/custom/OFPortDescVer12.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer12.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer13.java b/java_gen/templates/custom/OFPortDescVer13.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer13.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer14.java b/java_gen/templates/custom/OFPortDescVer14.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer14.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/interface/OFPortDesc.java b/java_gen/templates/custom/interface/OFPortDesc.java
new file mode 100644
index 0000000..ecf39f3
--- /dev/null
+++ b/java_gen/templates/custom/interface/OFPortDesc.java
@@ -0,0 +1,2 @@
+ // Additional method
+ boolean isEnabled();
\ No newline at end of file
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index f1d72b2..0b032ac 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -74,6 +74,13 @@
${impl_class}(${
", ".join("%s %s" %(prop.java_type.public_type, prop.name) for prop in msg.data_members) }) {
//:: for prop in msg.data_members:
+//:: if not prop.java_type.is_primitive and (not prop.default_value or prop.default_value != "null"):
+ if(${prop.name} == null) {
+ throw new NullPointerException("${msg.name}: property ${prop.name} cannot be null");
+ }
+//:: #endif
+//:: #endfor
+//:: for prop in msg.data_members:
this.${prop.name} = ${prop.name};
//:: #endfor
}
@@ -88,7 +95,7 @@
//:: include("_field_accessors.java", msg=msg, generate_setters=False, builder=False, has_parent=False)
//:: if os.path.exists("%s/custom/%s.java" % (template_dir, msg.name)):
- //:: include("custom/%s.java" % msg.name, msg=msg)
+ //:: include("custom/%s.java" % msg.name, msg=msg, version=version)
//:: #endif
//:: if msg.data_members:
@@ -124,7 +131,7 @@
//
//:: if os.path.exists("%s/custom/%s.Builder_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
return new ${impl_class}(
//:: for i, prop in enumerate(msg.data_members):
@@ -134,7 +141,7 @@
);
}
//:: if os.path.exists("%s/custom/%s.Builder.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder.java" % msg.name, msg=msg, has_parent=True)
+ //:: include("custom/%s.Builder.java" % msg.name, msg=msg, version=version, has_parent=True)
//:: #endif
}
@@ -164,7 +171,7 @@
//:: #endfor
//:: if os.path.exists("%s/custom/%s.Builder_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
return new ${impl_class}(
@@ -175,7 +182,7 @@
);
}
//:: if os.path.exists("%s/custom/%s.Builder.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
}
@@ -249,7 +256,7 @@
//:: if msg.data_members:
//:: if os.path.exists("%s/custom/%s.Reader_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
${impl_class} ${msg.variable_name} = new ${impl_class}(
${",\n ".join(
@@ -364,7 +371,7 @@
}
//:: if os.path.exists("%s/custom/%s_toString.java" % (template_dir, msg.name)):
- //:: include("custom/%s_toString.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s_toString.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: else:
@Override
public String toString() {
diff --git a/java_gen/templates/of_factories.java b/java_gen/templates/of_factories.java
index f9ec015..ba73286 100644
--- a/java_gen/templates/of_factories.java
+++ b/java_gen/templates/of_factories.java
@@ -51,7 +51,9 @@
private static class GenericReader implements OFMessageReader<OFMessage> {
public OFMessage readFrom(ChannelBuffer bb) throws OFParseError {
- short wireVersion = U8.f(bb.getByte(0));
+ if(!bb.readable())
+ return null;
+ short wireVersion = U8.f(bb.getByte(bb.readerIndex()));
OFFactory factory;
switch (wireVersion) {
//:: for v in versions:
diff --git a/java_gen/templates/of_interface.java b/java_gen/templates/of_interface.java
index a515ad1..18e2cf1 100644
--- a/java_gen/templates/of_interface.java
+++ b/java_gen/templates/of_interface.java
@@ -27,6 +27,7 @@
//::
//:: import itertools
//:: import re
+//:: import os
//:: include('_copyright.java')
//:: include('_autogen.java')
@@ -39,6 +40,10 @@
//:: for prop in msg.members:
${prop.java_type.public_type} ${prop.getter_name}()${ "" if prop.is_universal else " throws UnsupportedOperationException"};
//:: #endfor
+//:: if os.path.exists("%s/custom/interface/%s.java" % (template_dir, msg.name)):
+//:: include("custom/interface/%s.java" % msg.name, msg=msg)
+//:: #endif
+
void writeTo(ChannelBuffer channelBuffer);