61f8a9705bb5b630f24f6e5dcad8d292516c7c45
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / InstructionsDeserializer.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
2 package org.opendaylight.openflowjava.protocol.impl.util;\r
3 \r
4 import java.util.ArrayList;\r
5 import java.util.List;\r
6 \r
7 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;\r
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstructionBuilder;\r
9 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterInstruction;\r
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterInstructionBuilder;\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;\r
26 \r
27 import io.netty.buffer.ByteBuf;\r
28 \r
29 /**\r
30  * @author michal.polkorab\r
31  *\r
32  */\r
33 public class InstructionsDeserializer {\r
34     \r
35     private static final byte WRITE_APPLY_CLEAR_ACTION_LENGTH = 8;\r
36 \r
37     /**\r
38      * Creates list of instructions\r
39      * @param input\r
40      * @param length\r
41      * @return list of ofp_instruction\r
42      */\r
43     public static List<Instructions> createInstructions(ByteBuf input, int length) {\r
44         List<Instructions> instructions = new ArrayList<>();\r
45         if (input.readableBytes() != 0) {\r
46             int lengthOfInstructions = length;\r
47             while (lengthOfInstructions > 0) {\r
48                 InstructionsBuilder builder = new InstructionsBuilder();\r
49                 int type = input.readUnsignedShort();\r
50                 int instructionLength = input.readUnsignedShort();\r
51                 lengthOfInstructions -= instructionLength;\r
52                 switch (type) {\r
53                 case 1:\r
54                     createGotoTableInstruction(builder, input);\r
55                     break;\r
56                 case 2:\r
57                     createMetadataInstruction(builder, input);\r
58                     break;\r
59                 case 3:\r
60                     builder.setType(WriteActions.class);\r
61                     createActionRelatedInstruction(input, builder, instructionLength - WRITE_APPLY_CLEAR_ACTION_LENGTH);\r
62                     break;\r
63                 case 4:\r
64                     builder.setType(ApplyActions.class);\r
65                     createActionRelatedInstruction(input, builder, instructionLength - WRITE_APPLY_CLEAR_ACTION_LENGTH);\r
66                     break;\r
67                 case 5:\r
68                     builder.setType(ClearActions.class);\r
69                     createActionRelatedInstruction(input, builder, instructionLength - WRITE_APPLY_CLEAR_ACTION_LENGTH);\r
70                     break;\r
71                 case 6:\r
72                     builder.setType(Meter.class);\r
73                     MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();\r
74                     meterBuilder.setMeterId(input.readUnsignedInt());\r
75                     builder.addAugmentation(MeterIdInstruction.class, meterBuilder.build());\r
76                     break;\r
77                 case 65535:\r
78                     final byte EXPERIMENTER_HEADER_LENGTH = 8;\r
79                     builder.setType(Experimenter.class);\r
80                     ExperimenterInstructionBuilder expBuilder = new ExperimenterInstructionBuilder();\r
81                     expBuilder.setExperimenter(input.readUnsignedInt());\r
82                     int dataLength = instructionLength - EXPERIMENTER_HEADER_LENGTH;\r
83                     if (dataLength > 0) {\r
84                         byte[] data = new byte[dataLength];\r
85                         input.readBytes(data);\r
86                         expBuilder.setData(data);\r
87                     }\r
88                     builder.addAugmentation(ExperimenterInstruction.class, expBuilder.build());\r
89                     break;\r
90                 default:\r
91                     break;\r
92                 }\r
93                 instructions.add(builder.build());\r
94             }\r
95         }\r
96         return instructions;\r
97     }\r
98 \r
99     private static void createGotoTableInstruction(InstructionsBuilder builder,\r
100             ByteBuf input) {\r
101         final byte GOTO_TABLE_PADDING = 3;\r
102         builder.setType(GotoTable.class);\r
103         TableIdInstructionBuilder tableBuilder = new TableIdInstructionBuilder();\r
104         tableBuilder.setTableId(input.readUnsignedByte());\r
105         builder.addAugmentation(TableIdInstruction.class, tableBuilder.build());\r
106         input.skipBytes(GOTO_TABLE_PADDING);\r
107     }\r
108     \r
109     private static void createMetadataInstruction(InstructionsBuilder builder,\r
110             ByteBuf input) {\r
111         final byte WRITE_METADATA_PADDING = 4;\r
112         input.skipBytes(WRITE_METADATA_PADDING);\r
113         builder.setType(WriteMetadata.class);\r
114         MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();\r
115         byte[] metadata = new byte[Long.SIZE / Byte.SIZE];\r
116         input.readBytes(metadata);\r
117         metadataBuilder.setMetadata(metadata);\r
118         byte[] metadata_mask = new byte[Long.SIZE / Byte.SIZE];\r
119         input.readBytes(metadata_mask);\r
120         metadataBuilder.setMetadata(metadata_mask);\r
121         builder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());\r
122     }\r
123     \r
124     private static void createActionRelatedInstruction(ByteBuf input,\r
125             InstructionsBuilder builder, int instructionLength) {\r
126         final byte ACTIONS_RELATED_INSTRUCTION_PADDING = 4;\r
127         input.skipBytes(ACTIONS_RELATED_INSTRUCTION_PADDING);\r
128         ActionsInstructionBuilder actionsBuilder = new ActionsInstructionBuilder();\r
129         actionsBuilder.setActionsList(ActionsDeserializer.createActionsList(input, instructionLength));\r
130         builder.addAugmentation(ActionsInstruction.class, actionsBuilder.build());\r
131     }\r
132 \r
133 }\r