Required changes to support OF1.4, 1.5.

- OVS with OF1.4 passed `stc smoke` test
- OVS with OF1.5 still has issue
  As of OVS 2.5.0, OF1.5 mode responds with ill-formed of_meter_features_stats_reply
  org.projectfloodlight.openflow.exceptions.OFParseError: Wrong length: Expected=40(40), got=32
    at org.projectfloodlight.openflow.protocol.ver15.OFMeterFeaturesStatsReplyVer15$Reader.readFrom(OFMeterFeaturesStatsReplyVer15.java:281)

Change-Id: Ib78b9d92ecfb4bb667e24c4ee95bcd09aec160a6
diff --git a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
index 76019fd..100203f 100644
--- a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
+++ b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
@@ -1363,11 +1363,12 @@
         // The OF protocol requires us to start things off by sending the highest
         // version of the protocol supported.
 
-        // bitmap represents OF1.0, OF1.3, and OF1.4
+        // bitmap represents OF1.0, OF1.3, OF1.4, and OF1.5
         // see Sec. 7.5.1 of the OF1.3.4 spec
         U32 bitmap = U32.ofRaw((0b1 << OFVersion.OF_10.getWireVersion()) |
                                (0b1 << OFVersion.OF_13.getWireVersion()) |
-                               (0b1 << OFVersion.OF_14.getWireVersion()));
+                               (0b1 << OFVersion.OF_14.getWireVersion()) |
+                               (0b1 << OFVersion.OF_15.getWireVersion()));
         OFVersion version = Optional.ofNullable(ofVersion).orElse(OFVersion.OF_13);
         OFHelloElem hem = OFFactories.getFactory(version)
                 .buildHelloElemVersionbitmap()
diff --git a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
index ad4975a..bc9799c 100644
--- a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
+++ b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
@@ -123,7 +123,7 @@
         }
 
         int xid = sw.getNextTransactionId();
-        OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13)
+        OFRoleRequest rrm = sw.factory()
                 .buildRoleRequest()
                 .setRole(roleToSend)
                 .setXid(xid)
diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index 5e0fae4..2b003d1 100644
--- a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -327,6 +327,8 @@
                 sw.sendMsg(fact.buildFeaturesRequest().setXid(0).build());
                 break;
             case OF_13:
+            case OF_14:
+            case OF_15:
                 sw.sendMsg(fact.buildPortDescStatsRequest().setXid(0).build());
                 break;
             default:
@@ -977,11 +979,13 @@
             if (status.getReason() != OFPortReason.DELETE) {
                 return buildPortDescription(port);
             } else {
-                PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
-                Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
-                SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString()).build();
-                return new DefaultPortDescription(portNo, false, true, type,
-                                                  portSpeed(port), annotations);
+                PortDescription desc = buildPortDescription(port);
+                if (desc.isEnabled()) {
+                    return DefaultPortDescription.builder(desc)
+                            .isEnabled(false)
+                            .build();
+                }
+                return desc;
             }
         }
 
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index 6ed4cca..921ed93 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -134,6 +134,7 @@
             return new FlowModBuilderVer10(flowRule, factory, xid, driverService);
         case OF_13:
         case OF_14:
+        case OF_15:
             return new FlowModBuilderVer13(flowRule, factory, xid, driverService);
         default:
             throw new UnsupportedOperationException(
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
index 9fa03be..da30eea 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
@@ -53,6 +53,7 @@
 import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
 import org.projectfloodlight.openflow.protocol.OFMatchV3;
+import org.projectfloodlight.openflow.protocol.OFObject;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.protocol.action.OFAction;
 import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
@@ -268,6 +269,8 @@
             case OF_11:
             case OF_12:
             case OF_13:
+            case OF_14:
+            case OF_15:
                 return entry.getInstructions();
             default:
                 log.warn("Unknown OF version {}", entry.getVersion());
@@ -283,6 +286,8 @@
             case OF_11:
             case OF_12:
             case OF_13:
+            case OF_14:
+            case OF_15:
                 return entry.getInstructions();
             default:
                 log.warn("Unknown OF version {}", entry.getVersion());
@@ -743,7 +748,7 @@
             case VLAN_VID:
                 if (selectorInterpreter != null &&
                         selectorInterpreter.supported(ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
-                    if (match.getVersion().equals(OFVersion.OF_13)) {
+                    if (isOF13OrLater(match)) {
                         OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.VLAN_VID);
                         builder.extension(selectorInterpreter.mapOxm(oxm),
                                 deviceId);
@@ -1079,7 +1084,7 @@
             case OFDPA_OVID:
                 if (selectorInterpreter != null &&
                         selectorInterpreter.supported(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
-                    if (match.getVersion().equals(OFVersion.OF_13)) {
+                    if (isOF13OrLater(match)) {
                         OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.OFDPA_OVID);
                         builder.extension(selectorInterpreter.mapOxm(oxm),
                                           deviceId);
@@ -1091,7 +1096,7 @@
             case OFDPA_MPLS_L2_PORT:
                 if (selectorInterpreter != null &&
                         selectorInterpreter.supported(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
-                    if (match.getVersion().equals(OFVersion.OF_13)) {
+                    if (isOF13OrLater(match)) {
                         OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.OFDPA_MPLS_L2_PORT);
                         builder.extension(selectorInterpreter.mapOxm(oxm),
                                           deviceId);
@@ -1108,6 +1113,14 @@
         return builder.build();
     }
 
+    /**
+     * @param obj OpenFlow object to test
+     * @return true if OFObject is OF_13 or later
+     */
+    private static boolean isOF13OrLater(OFObject obj) {
+        return obj.getVersion().wireVersion >= OFVersion.OF_13.wireVersion;
+    }
+
     private DriverHandler getDriver(DeviceId devId) {
         Driver driver = driverService.getDriver(devId);
         DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, devId));
diff --git a/tools/test/topos/default.py b/tools/test/topos/default.py
index 16e8788..b58b780 100644
--- a/tools/test/topos/default.py
+++ b/tools/test/topos/default.py
@@ -7,6 +7,11 @@
 class AttMplsTopo( Topo ):
     "Internet Topology Zoo Specimen."
 
+    def addSwitch( self, name, **opts ):
+        kwargs = { 'protocols' : 'OpenFlow13' }
+        kwargs.update( opts )
+        return super(AttMplsTopo, self).addSwitch( name, **kwargs )
+
     def __init__( self ):
         "Create a topology."