Javadoc update
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / util / InstructionsSerializer.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 io.netty.buffer.ByteBuf;\r
5 \r
6 import java.util.List;\r
7 \r
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionsInstruction;\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.MetadataInstruction;\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstruction;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Instruction;\r
23 \r
24 /**\r
25  * Serializes ofp_instruction (OpenFlow v 1.3) structure\r
26  * @author michal.polkorab\r
27  * @author timotej.kubas\r
28  */\r
29 public abstract class InstructionsSerializer {\r
30 \r
31     /**\r
32      * Encodes instructions\r
33      * @param instructions List of instructions\r
34      * @param out output buffer\r
35      */\r
36     public static void encodeInstructions(List<Instructions> instructions, ByteBuf out) {\r
37         if (instructions != null) {\r
38             for (Instructions instruction : instructions) {\r
39                 Class<? extends Instruction> type = instruction.getType();\r
40                 if (type.equals(GotoTable.class)) {\r
41                     final byte GOTO_TABLE_TYPE = 1;\r
42                     final byte GOTO_TABLE_LENGTH = 8;\r
43                     final byte PADDING_IN_GOTO_TABLE = 3;\r
44                     writeTypeAndLength(out, GOTO_TABLE_TYPE, GOTO_TABLE_LENGTH);\r
45                     out.writeByte(instruction.getAugmentation(TableIdInstruction.class).getTableId());\r
46                     ByteBufUtils.padBuffer(PADDING_IN_GOTO_TABLE, out);\r
47                 } else if (type.equals(WriteMetadata.class)) {\r
48                     final byte WRITE_METADATA_TYPE = 2;\r
49                     final byte WRITE_METADATA_LENGTH = 24;\r
50                     final byte PADDING_IN_WRITE_METADATA = 4;\r
51                     writeTypeAndLength(out, WRITE_METADATA_TYPE, WRITE_METADATA_LENGTH);\r
52                     ByteBufUtils.padBuffer(PADDING_IN_WRITE_METADATA, out);\r
53                     MetadataInstruction metadata = instruction.getAugmentation(MetadataInstruction.class);\r
54                     out.writeBytes(metadata.getMetadata());\r
55                     out.writeBytes(metadata.getMetadataMask());\r
56                 } else if (type.equals(WriteActions.class)) {\r
57                     final byte WRITE_ACTIONS_TYPE = 3;\r
58                     writeActionsInstruction(out, instruction, WRITE_ACTIONS_TYPE);\r
59                 } else if (type.equals(ApplyActions.class)) {\r
60                     final byte APPLY_ACTIONS_TYPE = 4;\r
61                     writeActionsInstruction(out, instruction, APPLY_ACTIONS_TYPE);\r
62                 } else if (type.equals(ClearActions.class)) {\r
63                     final byte CLEAR_ACTIONS_TYPE = 5;\r
64                     final byte CLEAR_ACTIONS_LENGTH = 8;\r
65                     final byte PADDING_IN_CLEAR_ACTIONS = 4;\r
66                     writeTypeAndLength(out, CLEAR_ACTIONS_TYPE, CLEAR_ACTIONS_LENGTH);\r
67                     ByteBufUtils.padBuffer(PADDING_IN_CLEAR_ACTIONS, out);\r
68                 } else if (type.equals(Meter.class)) {\r
69                     final byte METER_TYPE = 6;\r
70                     final byte METER_LENGTH = 8;\r
71                     writeTypeAndLength(out, METER_TYPE, METER_LENGTH);\r
72                     out.writeInt(instruction.getAugmentation(MeterIdInstruction.class).getMeterId().intValue());\r
73                 } else if (type.equals(Experimenter.class)) {\r
74                     final byte EXPERIMENTER_TYPE = 7;\r
75                     final byte EXPERIMENTER_LENGTH = 8;\r
76                     ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);\r
77                     byte[] data = experimenter.getData();\r
78                     writeTypeAndLength(out, EXPERIMENTER_TYPE, EXPERIMENTER_LENGTH + data.length);\r
79                     out.writeInt(experimenter.getExperimenter().intValue());\r
80                     out.writeBytes(data);\r
81                 }\r
82             }\r
83         }\r
84         \r
85     }\r
86 \r
87     private static void writeTypeAndLength(ByteBuf out, int type, int length) {\r
88         out.writeShort(type);\r
89         out.writeShort(length);\r
90     }\r
91 \r
92     private static void writeActionsInstruction(ByteBuf out,\r
93             Instructions instruction, int type) {\r
94         final byte ACTIONS_INSTRUCTION_LENGTH = 8;\r
95         final byte PADDING_IN_ACTIONS_INSTRUCTION = 4;\r
96         out.writeShort(type);\r
97         List<ActionsList> actions = instruction.getAugmentation(ActionsInstruction.class).getActionsList();\r
98         out.writeShort(ACTIONS_INSTRUCTION_LENGTH + ActionsSerializer.computeLengthOfActions(actions));\r
99         ByteBufUtils.padBuffer(PADDING_IN_ACTIONS_INSTRUCTION, out);\r
100         ActionsSerializer.encodeActions(actions, out);\r
101     }\r
102     \r
103     /**\r
104      * Computes length of instructions\r
105      * @param instructions List of instructions\r
106      * @return length of instructions (in bytes)\r
107      */\r
108     public static int computeInstructionsLength(List<Instructions> instructions) {\r
109         int length = 0;\r
110         if (instructions != null) {\r
111             for (Instructions instruction : instructions) {\r
112                 Class<? extends Instruction> type = instruction.getType();\r
113                 if (type.equals(GotoTable.class)) {\r
114                     final byte GOTO_TABLE_LENGTH = 8;\r
115                     length += GOTO_TABLE_LENGTH;\r
116                 } else if (type.equals(WriteMetadata.class)) {\r
117                     final byte WRITE_METADATA_LENGTH = 24;\r
118                     length += WRITE_METADATA_LENGTH;\r
119                 } else if (type.equals(WriteActions.class)) {\r
120                     final byte WRITE_ACTIONS_LENGTH = 8;\r
121                     length += WRITE_ACTIONS_LENGTH + ActionsSerializer.computeLengthOfActions(\r
122                             instruction.getAugmentation(ActionsInstruction.class).getActionsList());\r
123                 } else if (type.equals(ApplyActions.class)) {\r
124                     final byte APPLY_ACTIONS_LENGTH = 8;\r
125                     length += APPLY_ACTIONS_LENGTH + ActionsSerializer.computeLengthOfActions(\r
126                             instruction.getAugmentation(ActionsInstruction.class).getActionsList());\r
127                 } else if (type.equals(ClearActions.class)) {\r
128                     final byte CLEAR_ACTIONS_LENGTH = 8;\r
129                     length += CLEAR_ACTIONS_LENGTH;\r
130                 } else if (type.equals(Meter.class)) {\r
131                     final byte METER_LENGTH = 8;\r
132                     length += METER_LENGTH;\r
133                 } else if (type.equals(Experimenter.class)) {\r
134                     final byte EXPERIMENTER_LENGTH = 8;\r
135                     ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);\r
136                     byte[] data = experimenter.getData();\r
137                     length += EXPERIMENTER_LENGTH + data.length;\r
138                 }\r
139             }\r
140         }\r
141         return length;\r
142     }\r
143 }\r