Merge "Fixing OF Multipart messages 1) So we have a MultipartRequestDesc message...
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / MultipartRequestMessageFactory.java
index db4b8537605af8e2c8b312b7efabb432f554d10b..f223c56203beecb0a000c97ee77e150d15831c6c 100644 (file)
@@ -21,12 +21,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestMessage;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregate;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDesc;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenter;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlow;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroup;\r
@@ -39,6 +41,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties;\r
 \r
 /**\r
+ * Translates MultipartRequest messages\r
  * @author timotej.kubas\r
  * @author michal.polkorab\r
  */\r
@@ -47,12 +50,12 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
     private static final int MESSAGE_LENGTH = 16;\r
     private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4;\r
     private static final byte TABLE_FEAT_HEADER_LENGTH = 4;\r
-    private static MultipartRequestMessageFactory instance; \r
-    \r
+    private static MultipartRequestMessageFactory instance;\r
+\r
     private MultipartRequestMessageFactory() {\r
         // singleton\r
     }\r
-    \r
+\r
     /**\r
      * @return singleton factory\r
      */\r
@@ -62,7 +65,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
         }\r
         return instance;\r
     }\r
-    \r
+\r
     @Override\r
     public void messageToBuffer(short version, ByteBuf out,\r
             MultipartRequestMessage message) {\r
@@ -70,8 +73,10 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
         out.writeShort(message.getType().getIntValue());\r
         out.writeShort(createMultipartRequestFlagsBitmask(message.getFlags()));\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_MESSAGE, out);\r
-        \r
-        if (message.getMultipartRequestBody() instanceof MultipartRequestFlow) {\r
+\r
+        if (message.getMultipartRequestBody() instanceof MultipartRequestDesc ){\r
+            encodeDescBody(message.getMultipartRequestBody(), out);\r
+        } else if (message.getMultipartRequestBody() instanceof MultipartRequestFlow) {\r
             encodeFlowBody(message.getMultipartRequestBody(), out);\r
         } else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregate) {\r
             encodeAggregateBody(message.getMultipartRequestBody(), out);\r
@@ -91,26 +96,119 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             encodeExperimenterBody(message.getMultipartRequestBody(), out);\r
         }\r
     }\r
-    \r
+\r
     @Override\r
     public int computeLength(MultipartRequestMessage message) {\r
-        // TODO\r
-        return MESSAGE_LENGTH;\r
+        return MESSAGE_LENGTH + computeBodyLength(message);\r
     }\r
     @Override\r
     public byte getMessageType() {\r
         return MESSAGE_TYPE;\r
-    } \r
-    \r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param message\r
+     * @return length of MultipartRequestMessage\r
+     */\r
+    public int computeBodyLength(MultipartRequestMessage message) {\r
+        int length = 0;\r
+        MultipartType type = message.getType();\r
+        if (type.equals(MultipartType.OFPMPFLOW)) {\r
+            final byte FLOW_BODY_LENGTH = 32;\r
+            MultipartRequestFlow body = (MultipartRequestFlow) message.getMultipartRequestBody();\r
+            length += FLOW_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch());\r
+        } else if (type.equals(MultipartType.OFPMPAGGREGATE)) {\r
+            final byte AGGREGATE_BODY_LENGTH = 32;\r
+            MultipartRequestAggregate body = (MultipartRequestAggregate) message.getMultipartRequestBody();\r
+            length += AGGREGATE_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch());\r
+        } else if (type.equals(MultipartType.OFPMPPORTSTATS)) {\r
+            final byte PORT_STATS_BODY_LENGTH = 8;\r
+            length += PORT_STATS_BODY_LENGTH;\r
+        } else if (type.equals(MultipartType.OFPMPQUEUE)) {\r
+            final byte QUEUE_BODY_LENGTH = 8;\r
+            length += QUEUE_BODY_LENGTH;\r
+        } else if (type.equals(MultipartType.OFPMPGROUP)) {\r
+            final byte GROUP_BODY_LENGTH = 8;\r
+            length += GROUP_BODY_LENGTH;\r
+        } else if (type.equals(MultipartType.OFPMPMETER)) {\r
+            final byte METER_BODY_LENGTH = 8;\r
+            length += METER_BODY_LENGTH;\r
+        } else if (type.equals(MultipartType.OFPMPMETERCONFIG)) {\r
+            final byte METER_CONFIG_BODY_LENGTH = 8;\r
+            length += METER_CONFIG_BODY_LENGTH;\r
+        } else if (type.equals(MultipartType.OFPMPTABLEFEATURES)) {\r
+            MultipartRequestTableFeatures body = (MultipartRequestTableFeatures) message.getMultipartRequestBody();\r
+            length += computeTableFeaturesLength(body);\r
+        } else if (type.equals(MultipartType.OFPMPEXPERIMENTER)) {\r
+            final byte EXPERIMENTER_BODY_LENGTH = 8;\r
+            MultipartRequestExperimenter body = (MultipartRequestExperimenter) message.getMultipartRequestBody();\r
+            length += EXPERIMENTER_BODY_LENGTH;\r
+            if (body.getData() != null) {\r
+                length += body.getData().length;\r
+            }\r
+        }\r
+        return length;\r
+    }\r
+\r
+    private static int computeTableFeaturesLength(MultipartRequestTableFeatures body) {\r
+        final byte TABLE_FEATURES_LENGTH = 64;\r
+        final byte STRUCTURE_HEADER_LENGTH = 4;\r
+        int length = 0;\r
+        if (body != null) {\r
+            List<TableFeatures> tableFeatures = body.getTableFeatures();\r
+            for (TableFeatures feature : tableFeatures) {\r
+                length += TABLE_FEATURES_LENGTH;\r
+                List<TableFeatureProperties> featureProperties = feature.getTableFeatureProperties();\r
+                if (featureProperties != null) {\r
+                    for (TableFeatureProperties featProp : featureProperties) {\r
+                        length += TABLE_FEAT_HEADER_LENGTH;\r
+                        if (featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class) != null) {\r
+                            InstructionRelatedTableFeatureProperty property =\r
+                                    featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class);\r
+                            length += property.getInstructions().size() * STRUCTURE_HEADER_LENGTH;\r
+                        } else if (featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class) != null) {\r
+                            NextTableRelatedTableFeatureProperty property =\r
+                                    featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class);\r
+                            length += property.getNextTableIds().size();\r
+                        } else if (featProp.getAugmentation(ActionRelatedTableFeatureProperty.class) != null) {\r
+                            ActionRelatedTableFeatureProperty property =\r
+                                    featProp.getAugmentation(ActionRelatedTableFeatureProperty.class);\r
+                            length += property.getActionsList().size() * STRUCTURE_HEADER_LENGTH;\r
+                        } else if (featProp.getAugmentation(OxmRelatedTableFeatureProperty.class) != null) {\r
+                            OxmRelatedTableFeatureProperty property =\r
+                                    featProp.getAugmentation(OxmRelatedTableFeatureProperty.class);\r
+                            length += property.getMatchEntries().size() * STRUCTURE_HEADER_LENGTH;\r
+                        } else if (featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class) != null) {\r
+                            ExperimenterRelatedTableFeatureProperty property =\r
+                                    featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class);\r
+                            length += 2 * (Integer.SIZE / Byte.SIZE);\r
+                            if (property.getData() != null) {\r
+                                length += property.getData().length;\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return length;\r
+    }\r
+\r
     private static int createMultipartRequestFlagsBitmask(MultipartRequestFlags flags) {\r
         int multipartRequestFlagsBitmask = 0;\r
         Map<Integer, Boolean> multipartRequestFlagsMap = new HashMap<>();\r
         multipartRequestFlagsMap.put(0, flags.isOFPMPFREQMORE());\r
-        \r
+\r
         multipartRequestFlagsBitmask = ByteBufUtils.fillBitMaskFromMap(multipartRequestFlagsMap);\r
         return multipartRequestFlagsBitmask;\r
     }\r
-    \r
+\r
+    private void encodeDescBody(MultipartRequestBody multipartRequestBody,\r
+            ByteBuf output) {\r
+        // The body of MultiPartRequestDesc is empty\r
+\r
+    }\r
+\r
     private static void encodeFlowBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3;\r
         final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4;\r
@@ -120,11 +218,11 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
         output.writeInt(flow.getOutPort().intValue());\r
         output.writeInt(flow.getOutGroup().intValue());\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02, output);\r
-        output.writeLong(flow.getCookie().longValue()); \r
+        output.writeLong(flow.getCookie().longValue());\r
         output.writeLong(flow.getCookieMask().longValue());\r
         MatchSerializer.encodeMatch(flow.getMatch(), output);\r
     }\r
-    \r
+\r
     private static void encodeAggregateBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01 = 3;\r
         final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02 = 4;\r
@@ -134,52 +232,55 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
         output.writeInt(aggregate.getOutPort().intValue());\r
         output.writeInt(aggregate.getOutGroup().intValue());\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02, output);\r
-        output.writeLong(aggregate.getCookie().longValue()); \r
+        output.writeLong(aggregate.getCookie().longValue());\r
         output.writeLong(aggregate.getCookieMask().longValue());\r
         MatchSerializer.encodeMatch(aggregate.getMatch(), output);\r
     }\r
-    \r
+\r
     private static void encodePortStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4;\r
         MultipartRequestPortStats portstats = (MultipartRequestPortStats) multipartRequestBody;\r
         output.writeInt(portstats.getPortNo().intValue());\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY, output);\r
     }\r
-    \r
+\r
     private static void encodeQueueBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         MultipartRequestQueue queue = (MultipartRequestQueue) multipartRequestBody;\r
         output.writeInt(queue.getPortNo().intValue());\r
         output.writeInt(queue.getQueueId().intValue());\r
     }\r
-    \r
+\r
     private static void encodeGroupStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4;\r
         MultipartRequestGroup groupStats = (MultipartRequestGroup) multipartRequestBody;\r
         output.writeInt(groupStats.getGroupId().intValue());\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY, output);\r
     }\r
-    \r
+\r
     private static void encodeMeterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4;\r
         MultipartRequestMeter meter = (MultipartRequestMeter) multipartRequestBody;\r
         output.writeInt(meter.getMeterId().intValue());\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_BODY, output);\r
     }\r
-    \r
+\r
     private static void encodeMeterConfigBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4;\r
         MultipartRequestMeterConfig meterConfig = (MultipartRequestMeterConfig) multipartRequestBody;\r
         output.writeInt(meterConfig.getMeterId().intValue());\r
         ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY, output);\r
     }\r
-    \r
+\r
     private static void encodeExperimenterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         MultipartRequestExperimenter experimenter = (MultipartRequestExperimenter) multipartRequestBody;\r
         output.writeInt(experimenter.getExperimenter().intValue());\r
         output.writeInt(experimenter.getExpType().intValue());\r
-        output.writeBytes(experimenter.getData());\r
+        byte[] data = experimenter.getData();\r
+        if (data != null) {\r
+            output.writeBytes(data);\r
+        }\r
     }\r
-    \r
+\r
     private static void encodeTableFeaturesBody(MultipartRequestBody multipartRequestBody, ByteBuf output) {\r
         if (multipartRequestBody != null) {\r
             MultipartRequestTableFeatures tableFeatures = (MultipartRequestTableFeatures) multipartRequestBody;\r
@@ -197,7 +298,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             }\r
         }\r
     }\r
-    \r
+\r
     private static void writeTableFeatureProperties(ByteBuf output, List<TableFeatureProperties> props) {\r
         if (props != null) {\r
             for (TableFeatureProperties property : props) {\r
@@ -250,7 +351,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
                 } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {\r
                     final int EXPERIMENTER_MISS_CODE = 65535; // 0xFFFF\r
                     writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_MISS_CODE);\r
-                } \r
+                }\r
             }\r
         }\r
     }\r
@@ -269,7 +370,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             output.writeShort(length);\r
         }\r
     }\r
-    \r
+\r
     private static void writeNextTableRelatedTableProperty(ByteBuf output,\r
             TableFeatureProperties property, byte code) {\r
         output.writeShort(code);\r
@@ -285,7 +386,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             output.writeShort(length);\r
         }\r
     }\r
-    \r
+\r
     private static void writeActionsRelatedTableProperty(ByteBuf output,\r
             TableFeatureProperties property, byte code) {\r
         output.writeShort(code);\r
@@ -300,7 +401,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             output.writeShort(length);\r
         }\r
     }\r
-    \r
+\r
     private static void writeOxmRelatedTableProperty(ByteBuf output,\r
             TableFeatureProperties property, byte code) {\r
         output.writeShort(code);\r
@@ -315,7 +416,7 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             output.writeShort(length);\r
         }\r
     }\r
-    \r
+\r
     private static void writeExperimenterRelatedTableProperty(ByteBuf output,\r
             TableFeatureProperties property, int code) {\r
         output.writeShort(code);\r
@@ -334,12 +435,12 @@ public class MultipartRequestMessageFactory implements OFSerializer<MultipartReq
             output.writeInt(exp.getExpType().intValue());\r
         }\r
     }\r
-    \r
+\r
     private static int createTableConfigBitmask(TableConfig tableConfig) {\r
         int tableConfigBitmask = 0;\r
         Map<Integer, Boolean> tableConfigMap = new HashMap<>();\r
         tableConfigMap.put(3, tableConfig.isOFPTCDEPRECATEDMASK());\r
-        \r
+\r
         tableConfigBitmask = ByteBufUtils.fillBitMaskFromMap(tableConfigMap);\r
         return tableConfigBitmask;\r
     }\r