Merge "OPNFLWPLUG-929 : Remove deprecated guava library"
[openflowplugin.git] / openflowjava / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / MultipartReplyMessageFactory.java
1 /*
2  * Copyright (c) 2015 NetIDE Consortium and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowjava.protocol.impl.serialization.factories;
9
10 import io.netty.buffer.ByteBuf;
11 import io.netty.buffer.UnpooledByteBufAllocator;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector;
18 import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
19 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
20 import org.opendaylight.openflowjava.protocol.impl.util.ListSerializer;
21 import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMaker;
22 import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory;
23 import org.opendaylight.openflowjava.util.ByteBufUtils;
24 import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdTableFeatureProperty;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterBandCommons;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.MeterBand;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDrop;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemark;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.experimenter._case.MeterBandExperimenter;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStats;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.group.stats.BucketStats;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDesc;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStats;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.meter.stats.MeterBandStats;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.MeterConfig;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.meter.config.Bands;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDesc;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeatures;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
101
102 /**
103  * Translates MultipartReply messages.
104  *
105  * @author giuseppex.petralia@intel.com
106  */
107 public class MultipartReplyMessageFactory implements OFSerializer<MultipartReplyMessage>, SerializerRegistryInjector {
108
109     private static final byte MESSAGE_TYPE = 19;
110     private SerializerRegistry registry;
111     private static final byte PADDING = 4;
112     private static final byte PORT_DESC_PADDING_1 = 4;
113     private static final byte PORT_DESC_PADDING_2 = 2;
114     private static final int FLOW_STATS_LENGTH_INDEX = 0;
115     private static final byte FLOW_STATS_PADDING_1 = 1;
116     private static final byte FLOW_STATS_PADDING_2 = 6;
117     private static final byte AGGREGATE_PADDING = 4;
118     private static final byte TABLE_PADDING = 3;
119     private static final byte PORT_STATS_PADDING = 4;
120     private static final byte GROUP_STATS_PADDING_1 = 2;
121     private static final byte GROUP_STATS_PADDING_2 = 4;
122     private static final int GROUP_STATS_LENGTH_INDEX = 0;
123     private static final int GROUP_DESC_LENGTH_INDEX = 0;
124     private static final int BUCKET_LENGTH_INDEX = 0;
125     private static final byte GROUP_DESC_PADDING = 1;
126     private static final byte BUCKET_PADDING = 4;
127     private static final int METER_LENGTH_INDEX = 4;
128     private static final byte METER_PADDING = 6;
129     private static final int METER_CONFIG_LENGTH_INDEX = 0;
130     private static final short LENGTH_OF_METER_BANDS = 16;
131     private static final byte METER_FEATURES_PADDING = 2;
132     private static final int TABLE_FEATURES_LENGTH_INDEX = 0;
133     private static final byte TABLE_FEATURES_PADDING = 5;
134     private static final byte INSTRUCTIONS_CODE = 0;
135     private static final byte INSTRUCTIONS_MISS_CODE = 1;
136     private static final byte NEXT_TABLE_CODE = 2;
137     private static final byte NEXT_TABLE_MISS_CODE = 3;
138     private static final byte WRITE_ACTIONS_CODE = 4;
139     private static final byte WRITE_ACTIONS_MISS_CODE = 5;
140     private static final byte APPLY_ACTIONS_CODE = 6;
141     private static final byte APPLY_ACTIONS_MISS_CODE = 7;
142     private static final byte MATCH_CODE = 8;
143     private static final byte WILDCARDS_CODE = 10;
144     private static final byte WRITE_SETFIELD_CODE = 12;
145     private static final byte WRITE_SETFIELD_MISS_CODE = 13;
146     private static final byte APPLY_SETFIELD_CODE = 14;
147     private static final byte APPLY_SETFIELD_MISS_CODE = 15;
148
149     @Override
150     public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) {
151         this.registry = serializerRegistry;
152     }
153
154     @Override
155     public void serialize(final MultipartReplyMessage message, final ByteBuf outBuffer) {
156         ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH);
157         outBuffer.writeShort(message.getType().getIntValue());
158         writeFlags(message.getFlags(), outBuffer);
159         outBuffer.writeZero(PADDING);
160         switch (message.getType()) {
161             case OFPMPDESC:
162                 serializeDescBody(message.getMultipartReplyBody(), outBuffer);
163                 break;
164             case OFPMPFLOW:
165                 serializeFlowBody(message.getMultipartReplyBody(), outBuffer, message);
166                 break;
167             case OFPMPAGGREGATE:
168                 serializeAggregateBody(message.getMultipartReplyBody(), outBuffer);
169                 break;
170             case OFPMPTABLE:
171                 serializeTableBody(message.getMultipartReplyBody(), outBuffer);
172                 break;
173             case OFPMPPORTSTATS:
174                 serializePortStatsBody(message.getMultipartReplyBody(), outBuffer);
175                 break;
176             case OFPMPQUEUE:
177                 serializeQueueBody(message.getMultipartReplyBody(), outBuffer);
178                 break;
179             case OFPMPGROUP:
180                 serializeGroupBody(message.getMultipartReplyBody(), outBuffer);
181                 break;
182             case OFPMPGROUPDESC:
183                 serializeGroupDescBody(message.getMultipartReplyBody(), outBuffer, message);
184                 break;
185             case OFPMPGROUPFEATURES:
186                 serializeGroupFeaturesBody(message.getMultipartReplyBody(), outBuffer);
187                 break;
188             case OFPMPMETER:
189                 serializeMeterBody(message.getMultipartReplyBody(), outBuffer);
190                 break;
191             case OFPMPMETERCONFIG:
192                 serializeMeterConfigBody(message.getMultipartReplyBody(), outBuffer);
193                 break;
194             case OFPMPMETERFEATURES:
195                 serializeMeterFeaturesBody(message.getMultipartReplyBody(), outBuffer);
196                 break;
197             case OFPMPTABLEFEATURES:
198                 serializeTableFeaturesBody(message.getMultipartReplyBody(), outBuffer);
199                 break;
200             case OFPMPPORTDESC:
201                 serializePortDescBody(message.getMultipartReplyBody(), outBuffer);
202                 break;
203             case OFPMPEXPERIMENTER:
204                 serializeExperimenterBody(message.getMultipartReplyBody(), outBuffer);
205                 break;
206             default:
207                 break;
208         }
209         ByteBufUtils.updateOFHeaderLength(outBuffer);
210     }
211
212     private void serializeExperimenterBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
213         MultipartReplyExperimenterCase experimenterCase = (MultipartReplyExperimenterCase) body;
214         MultipartReplyExperimenter experimenterBody = experimenterCase.getMultipartReplyExperimenter();
215         // TODO: experimenterBody does not have get methods
216     }
217
218     private void writeFlags(final MultipartRequestFlags flags, final ByteBuf outBuffer) {
219         Map<Integer, Boolean> map = new HashMap<>();
220         map.put(0, flags.isOFPMPFREQMORE());
221         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
222         outBuffer.writeShort(bitmap);
223     }
224
225     private void serializeTableFeaturesBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
226         MultipartReplyTableFeaturesCase tableFeaturesCase = (MultipartReplyTableFeaturesCase) body;
227         MultipartReplyTableFeatures tableFeatures = tableFeaturesCase.getMultipartReplyTableFeatures();
228         for (TableFeatures tableFeature : tableFeatures.getTableFeatures()) {
229             ByteBuf tableFeatureBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
230             tableFeatureBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
231             tableFeatureBuff.writeByte(tableFeature.getTableId());
232             tableFeatureBuff.writeZero(TABLE_FEATURES_PADDING);
233             write32String(tableFeature.getName(), tableFeatureBuff);
234             tableFeatureBuff.writeBytes(tableFeature.getMetadataMatch());
235             tableFeatureBuff.writeZero(64 - tableFeature.getMetadataMatch().length);
236             tableFeatureBuff.writeBytes(tableFeature.getMetadataWrite());
237             tableFeatureBuff.writeZero(64 - tableFeature.getMetadataWrite().length);
238             writeTableConfig(tableFeature.getConfig(), tableFeatureBuff);
239             tableFeatureBuff.writeInt(tableFeature.getMaxEntries().intValue());
240             for (TableFeatureProperties tableFeatureProp : tableFeature.getTableFeatureProperties()) {
241                 switch (tableFeatureProp.getType()) {
242                     case OFPTFPTINSTRUCTIONS:
243                         writeInstructionRelatedTableProperty(tableFeatureBuff, tableFeatureProp, INSTRUCTIONS_CODE);
244                         break;
245                     case OFPTFPTINSTRUCTIONSMISS:
246                         writeInstructionRelatedTableProperty(tableFeatureBuff, tableFeatureProp,
247                                 INSTRUCTIONS_MISS_CODE);
248                         break;
249                     case OFPTFPTNEXTTABLES:
250                         writeNextTableRelatedTableProperty(tableFeatureBuff, tableFeatureProp, NEXT_TABLE_CODE);
251                         break;
252                     case OFPTFPTNEXTTABLESMISS:
253                         writeNextTableRelatedTableProperty(tableFeatureBuff, tableFeatureProp, NEXT_TABLE_MISS_CODE);
254                         break;
255                     case OFPTFPTWRITEACTIONS:
256                         writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_ACTIONS_CODE);
257                         break;
258                     case OFPTFPTWRITEACTIONSMISS:
259                         writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_ACTIONS_MISS_CODE);
260                         break;
261                     case OFPTFPTAPPLYACTIONS:
262                         writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_ACTIONS_CODE);
263                         break;
264                     case OFPTFPTAPPLYACTIONSMISS:
265                         writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_ACTIONS_MISS_CODE);
266                         break;
267                     case OFPTFPTMATCH:
268                         writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, MATCH_CODE);
269                         break;
270                     case OFPTFPTWILDCARDS:
271                         writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WILDCARDS_CODE);
272                         break;
273                     case OFPTFPTWRITESETFIELD:
274                         writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_SETFIELD_CODE);
275                         break;
276                     case OFPTFPTWRITESETFIELDMISS:
277                         writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_SETFIELD_MISS_CODE);
278                         break;
279                     case OFPTFPTAPPLYSETFIELD:
280                         writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_SETFIELD_CODE);
281                         break;
282                     case OFPTFPTAPPLYSETFIELDMISS:
283                         writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_SETFIELD_MISS_CODE);
284                         break;
285                     case OFPTFPTEXPERIMENTER:
286                         writeExperimenterRelatedTableProperty(tableFeatureBuff, tableFeatureProp);
287                         break;
288                     case OFPTFPTEXPERIMENTERMISS:
289                         writeExperimenterRelatedTableProperty(tableFeatureBuff, tableFeatureProp);
290                         break;
291                     default:
292                         break;
293                 }
294             }
295             tableFeatureBuff.setShort(TABLE_FEATURES_LENGTH_INDEX, tableFeatureBuff.readableBytes());
296             outBuffer.writeBytes(tableFeatureBuff);
297         }
298     }
299
300     private void writeExperimenterRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property) {
301         long expId = property.getAugmentation(ExperimenterIdTableFeatureProperty.class).getExperimenter().getValue();
302         OFSerializer<TableFeatureProperties> serializer = registry.getSerializer(ExperimenterSerializerKeyFactory
303                 .createMultipartRequestTFSerializerKey(EncodeConstants.OF13_VERSION_ID, expId));
304         serializer.serialize(property, output);
305     }
306
307     private void writeOxmRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property,
308             final byte code) {
309         final int startIndex = output.writerIndex();
310         output.writeShort(code);
311         int lengthIndex = output.writerIndex();
312         output.writeShort(EncodeConstants.EMPTY_LENGTH);
313         List<MatchEntry> entries = property.getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntry();
314         if (entries != null) {
315             TypeKeyMaker<MatchEntry> keyMaker = TypeKeyMakerFactory
316                     .createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID);
317             ListSerializer.serializeHeaderList(entries, keyMaker, registry, output);
318         }
319         int length = output.writerIndex() - startIndex;
320         output.setShort(lengthIndex, length);
321         output.writeZero(paddingNeeded(length));
322     }
323
324     private void writeActionsRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property,
325             final byte code) {
326         final int startIndex = output.writerIndex();
327         output.writeShort(code);
328         int lengthIndex = output.writerIndex();
329         output.writeShort(EncodeConstants.EMPTY_LENGTH);
330         List<Action> actions = property.getAugmentation(ActionRelatedTableFeatureProperty.class).getAction();
331         if (actions != null) {
332             TypeKeyMaker<Action> keyMaker = TypeKeyMakerFactory.createActionKeyMaker(EncodeConstants.OF13_VERSION_ID);
333             ListSerializer.serializeHeaderList(actions, keyMaker, registry, output);
334         }
335         int length = output.writerIndex() - startIndex;
336         output.setShort(lengthIndex, length);
337         output.writeZero(paddingNeeded(length));
338     }
339
340     private static void writeNextTableRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property,
341             final byte code) {
342         final int startIndex = output.writerIndex();
343         output.writeShort(code);
344         int lengthIndex = output.writerIndex();
345         output.writeShort(EncodeConstants.EMPTY_LENGTH);
346         List<NextTableIds> nextTableIds = property.getAugmentation(NextTableRelatedTableFeatureProperty.class)
347                 .getNextTableIds();
348         if (nextTableIds != null) {
349             for (NextTableIds next : nextTableIds) {
350                 output.writeByte(next.getTableId());
351             }
352         }
353         int length = output.writerIndex() - startIndex;
354         output.setShort(lengthIndex, length);
355         output.writeZero(paddingNeeded(length));
356     }
357
358     private void writeInstructionRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property,
359             final byte code) {
360         final int startIndex = output.writerIndex();
361         output.writeShort(code);
362         int lengthIndex = output.writerIndex();
363         output.writeShort(EncodeConstants.EMPTY_LENGTH);
364         List<Instruction> instructions = property.getAugmentation(InstructionRelatedTableFeatureProperty.class)
365                 .getInstruction();
366         if (instructions != null) {
367             TypeKeyMaker<Instruction> keyMaker = TypeKeyMakerFactory
368                     .createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID);
369             ListSerializer.serializeHeaderList(instructions, keyMaker, registry, output);
370         }
371         int length = output.writerIndex() - startIndex;
372         output.setShort(lengthIndex, length);
373         output.writeZero(paddingNeeded(length));
374     }
375
376     private static int paddingNeeded(final int length) {
377         int paddingRemainder = length % EncodeConstants.PADDING;
378         int result = 0;
379         if (paddingRemainder != 0) {
380             result = EncodeConstants.PADDING - paddingRemainder;
381         }
382         return result;
383     }
384
385     private void writeTableConfig(final TableConfig tableConfig, final ByteBuf outBuffer) {
386         Map<Integer, Boolean> map = new HashMap<>();
387         map.put(0, tableConfig.isOFPTCDEPRECATEDMASK());
388         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
389         outBuffer.writeInt(bitmap);
390     }
391
392     private void serializeMeterFeaturesBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
393         MultipartReplyMeterFeaturesCase meterFeaturesCase = (MultipartReplyMeterFeaturesCase) body;
394         MultipartReplyMeterFeatures meterFeatures = meterFeaturesCase.getMultipartReplyMeterFeatures();
395         outBuffer.writeInt(meterFeatures.getMaxMeter().intValue());
396         writeBandTypes(meterFeatures.getBandTypes(), outBuffer);
397         writeMeterFlags(meterFeatures.getCapabilities(), outBuffer);
398         outBuffer.writeByte(meterFeatures.getMaxBands());
399         outBuffer.writeByte(meterFeatures.getMaxColor());
400         outBuffer.writeZero(METER_FEATURES_PADDING);
401     }
402
403     private void writeBandTypes(final MeterBandTypeBitmap bandTypes, final ByteBuf outBuffer) {
404         Map<Integer, Boolean> map = new HashMap<>();
405         map.put(0, bandTypes.isOFPMBTDROP());
406         map.put(1, bandTypes.isOFPMBTDSCPREMARK());
407         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
408         outBuffer.writeInt(bitmap);
409     }
410
411     private void serializeMeterConfigBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
412         MultipartReplyMeterConfigCase meterConfigCase = (MultipartReplyMeterConfigCase) body;
413         MultipartReplyMeterConfig meter = meterConfigCase.getMultipartReplyMeterConfig();
414         for (MeterConfig meterConfig : meter.getMeterConfig()) {
415             ByteBuf meterConfigBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
416             meterConfigBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
417             writeMeterFlags(meterConfig.getFlags(), meterConfigBuff);
418             meterConfigBuff.writeInt(meterConfig.getMeterId().getValue().intValue());
419             for (Bands currentBand : meterConfig.getBands()) {
420                 MeterBand meterBand = currentBand.getMeterBand();
421                 if (meterBand instanceof MeterBandDropCase) {
422                     MeterBandDropCase dropBandCase = (MeterBandDropCase) meterBand;
423                     MeterBandDrop dropBand = dropBandCase.getMeterBandDrop();
424                     writeBandCommonFields(dropBand, meterConfigBuff);
425                 } else if (meterBand instanceof MeterBandDscpRemarkCase) {
426                     MeterBandDscpRemarkCase dscpRemarkBandCase = (MeterBandDscpRemarkCase) meterBand;
427                     MeterBandDscpRemark dscpRemarkBand = dscpRemarkBandCase.getMeterBandDscpRemark();
428                     writeBandCommonFields(dscpRemarkBand, meterConfigBuff);
429                 } else if (meterBand instanceof MeterBandExperimenterCase) {
430                     MeterBandExperimenterCase experimenterBandCase = (MeterBandExperimenterCase) meterBand;
431                     MeterBandExperimenter experimenterBand = experimenterBandCase.getMeterBandExperimenter();
432                     writeBandCommonFields(experimenterBand, meterConfigBuff);
433                 }
434             }
435             meterConfigBuff.setShort(METER_CONFIG_LENGTH_INDEX, meterConfigBuff.readableBytes());
436             outBuffer.writeBytes(meterConfigBuff);
437         }
438     }
439
440     private static void writeBandCommonFields(final MeterBandCommons meterBand, final ByteBuf outBuffer) {
441         outBuffer.writeShort(meterBand.getType().getIntValue());
442         outBuffer.writeShort(LENGTH_OF_METER_BANDS);
443         outBuffer.writeInt(meterBand.getRate().intValue());
444         outBuffer.writeInt(meterBand.getBurstSize().intValue());
445     }
446
447     private void writeMeterFlags(final MeterFlags flags, final ByteBuf outBuffer) {
448         Map<Integer, Boolean> map = new HashMap<>();
449         map.put(0, flags.isOFPMFKBPS());
450         map.put(1, flags.isOFPMFPKTPS());
451         map.put(2, flags.isOFPMFBURST());
452         map.put(3, flags.isOFPMFSTATS());
453         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
454         outBuffer.writeShort(bitmap);
455     }
456
457     private void serializeMeterBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
458         MultipartReplyMeterCase meterCase = (MultipartReplyMeterCase) body;
459         MultipartReplyMeter meter = meterCase.getMultipartReplyMeter();
460         for (MeterStats meterStats : meter.getMeterStats()) {
461             ByteBuf meterStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
462             meterStatsBuff.writeInt(meterStats.getMeterId().getValue().intValue());
463             meterStatsBuff.writeInt(EncodeConstants.EMPTY_LENGTH);
464             meterStatsBuff.writeZero(METER_PADDING);
465             meterStatsBuff.writeInt(meterStats.getFlowCount().intValue());
466             meterStatsBuff.writeLong(meterStats.getPacketInCount().longValue());
467             meterStatsBuff.writeLong(meterStats.getByteInCount().longValue());
468             meterStatsBuff.writeInt(meterStats.getDurationSec().intValue());
469             meterStatsBuff.writeInt(meterStats.getDurationNsec().intValue());
470             for (MeterBandStats meterBandStats : meterStats.getMeterBandStats()) {
471                 meterStatsBuff.writeLong(meterBandStats.getPacketBandCount().longValue());
472                 meterStatsBuff.writeLong(meterBandStats.getByteBandCount().longValue());
473             }
474             meterStatsBuff.setInt(METER_LENGTH_INDEX, meterStatsBuff.readableBytes());
475             outBuffer.writeBytes(meterStatsBuff);
476         }
477     }
478
479     private void serializeGroupFeaturesBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
480         MultipartReplyGroupFeaturesCase groupFeaturesCase = (MultipartReplyGroupFeaturesCase) body;
481         MultipartReplyGroupFeatures groupFeatures = groupFeaturesCase.getMultipartReplyGroupFeatures();
482         writeGroupTypes(groupFeatures.getTypes(), outBuffer);
483         writeGroupCapabilities(groupFeatures.getCapabilities(), outBuffer);
484         for (Long maxGroups : groupFeatures.getMaxGroups()) {
485             outBuffer.writeInt(maxGroups.intValue());
486         }
487         for (ActionType action : groupFeatures.getActionsBitmap()) {
488             writeActionType(action, outBuffer);
489         }
490     }
491
492     private void writeActionType(final ActionType action, final ByteBuf outBuffer) {
493         Map<Integer, Boolean> map = new HashMap<>();
494         map.put(0, action.isOFPATOUTPUT());
495         map.put(1, action.isOFPATCOPYTTLOUT());
496         map.put(2, action.isOFPATCOPYTTLIN());
497         map.put(3, action.isOFPATSETMPLSTTL());
498         map.put(4, action.isOFPATDECMPLSTTL());
499         map.put(5, action.isOFPATPUSHVLAN());
500         map.put(6, action.isOFPATPOPVLAN());
501         map.put(7, action.isOFPATPUSHMPLS());
502         map.put(8, action.isOFPATPOPMPLS());
503         map.put(9, action.isOFPATSETQUEUE());
504         map.put(10, action.isOFPATGROUP());
505         map.put(11, action.isOFPATSETNWTTL());
506         map.put(12, action.isOFPATDECNWTTL());
507         map.put(13, action.isOFPATSETFIELD());
508         map.put(14, action.isOFPATPUSHPBB());
509         map.put(15, action.isOFPATPOPPBB());
510         map.put(16, action.isOFPATEXPERIMENTER());
511         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
512         outBuffer.writeInt(bitmap);
513     }
514
515     private void writeGroupCapabilities(final GroupCapabilities capabilities, final ByteBuf outBuffer) {
516         Map<Integer, Boolean> map = new HashMap<>();
517         map.put(0, capabilities.isOFPGFCSELECTWEIGHT());
518         map.put(1, capabilities.isOFPGFCSELECTLIVENESS());
519         map.put(2, capabilities.isOFPGFCCHAINING());
520         map.put(3, capabilities.isOFPGFCCHAININGCHECKS());
521         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
522         outBuffer.writeInt(bitmap);
523     }
524
525     private void writeGroupTypes(final GroupTypes types, final ByteBuf outBuffer) {
526         Map<Integer, Boolean> map = new HashMap<>();
527         map.put(0, types.isOFPGTALL());
528         map.put(1, types.isOFPGTSELECT());
529         map.put(2, types.isOFPGTINDIRECT());
530         map.put(3, types.isOFPGTFF());
531         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
532         outBuffer.writeInt(bitmap);
533     }
534
535     private void serializeGroupDescBody(final MultipartReplyBody body, final ByteBuf outBuffer,
536             final MultipartReplyMessage message) {
537         MultipartReplyGroupDescCase groupDescCase = (MultipartReplyGroupDescCase) body;
538         MultipartReplyGroupDesc group = groupDescCase.getMultipartReplyGroupDesc();
539         for (GroupDesc groupDesc : group.getGroupDesc()) {
540             ByteBuf groupDescBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
541             groupDescBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
542             groupDescBuff.writeByte(groupDesc.getType().getIntValue());
543             groupDescBuff.writeZero(GROUP_DESC_PADDING);
544             groupDescBuff.writeInt(groupDesc.getGroupId().getValue().intValue());
545             for (BucketsList bucket : groupDesc.getBucketsList()) {
546                 ByteBuf bucketBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
547                 bucketBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
548                 bucketBuff.writeShort(bucket.getWeight());
549                 bucketBuff.writeInt(bucket.getWatchPort().getValue().intValue());
550                 bucketBuff.writeInt(bucket.getWatchGroup().intValue());
551                 bucketBuff.writeZero(BUCKET_PADDING);
552                 ListSerializer.serializeList(bucket.getAction(),
553                         TypeKeyMakerFactory.createActionKeyMaker(message.getVersion()), registry, bucketBuff);
554                 bucketBuff.setShort(BUCKET_LENGTH_INDEX, bucketBuff.readableBytes());
555                 groupDescBuff.writeBytes(bucketBuff);
556             }
557             groupDescBuff.setShort(GROUP_DESC_LENGTH_INDEX, groupDescBuff.readableBytes());
558             outBuffer.writeBytes(groupDescBuff);
559         }
560     }
561
562     private void serializeGroupBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
563         MultipartReplyGroupCase groupCase = (MultipartReplyGroupCase) body;
564         MultipartReplyGroup group = groupCase.getMultipartReplyGroup();
565         for (GroupStats groupStats : group.getGroupStats()) {
566             ByteBuf groupStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
567             groupStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
568             groupStatsBuff.writeZero(GROUP_STATS_PADDING_1);
569             groupStatsBuff.writeInt(groupStats.getGroupId().getValue().intValue());
570             groupStatsBuff.writeInt(groupStats.getRefCount().intValue());
571             groupStatsBuff.writeZero(GROUP_STATS_PADDING_2);
572             groupStatsBuff.writeLong(groupStats.getPacketCount().longValue());
573             groupStatsBuff.writeLong(groupStats.getByteCount().longValue());
574             groupStatsBuff.writeInt(groupStats.getDurationSec().intValue());
575             groupStatsBuff.writeInt(groupStats.getDurationNsec().intValue());
576             for (BucketStats bucketStats : groupStats.getBucketStats()) {
577                 groupStatsBuff.writeLong(bucketStats.getPacketCount().longValue());
578                 groupStatsBuff.writeLong(bucketStats.getByteCount().longValue());
579             }
580             groupStatsBuff.setShort(GROUP_STATS_LENGTH_INDEX, groupStatsBuff.readableBytes());
581             outBuffer.writeBytes(groupStatsBuff);
582         }
583     }
584
585     private void serializeQueueBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
586         MultipartReplyQueueCase queueCase = (MultipartReplyQueueCase) body;
587         MultipartReplyQueue queue = queueCase.getMultipartReplyQueue();
588         for (QueueStats queueStats : queue.getQueueStats()) {
589             outBuffer.writeInt(queueStats.getPortNo().intValue());
590             outBuffer.writeInt(queueStats.getQueueId().intValue());
591             outBuffer.writeLong(queueStats.getTxBytes().longValue());
592             outBuffer.writeLong(queueStats.getTxPackets().longValue());
593             outBuffer.writeLong(queueStats.getTxErrors().longValue());
594             outBuffer.writeInt(queueStats.getDurationSec().intValue());
595             outBuffer.writeInt(queueStats.getDurationNsec().intValue());
596         }
597     }
598
599     private void serializePortStatsBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
600         MultipartReplyPortStatsCase portStatsCase = (MultipartReplyPortStatsCase) body;
601         MultipartReplyPortStats portStats = portStatsCase.getMultipartReplyPortStats();
602         for (PortStats portStat : portStats.getPortStats()) {
603             outBuffer.writeInt(portStat.getPortNo().intValue());
604             outBuffer.writeZero(PORT_STATS_PADDING);
605             outBuffer.writeLong(portStat.getRxPackets().longValue());
606             outBuffer.writeLong(portStat.getTxPackets().longValue());
607             outBuffer.writeLong(portStat.getRxBytes().longValue());
608             outBuffer.writeLong(portStat.getTxBytes().longValue());
609             outBuffer.writeLong(portStat.getRxDropped().longValue());
610             outBuffer.writeLong(portStat.getTxDropped().longValue());
611             outBuffer.writeLong(portStat.getRxErrors().longValue());
612             outBuffer.writeLong(portStat.getTxErrors().longValue());
613             outBuffer.writeLong(portStat.getRxFrameErr().longValue());
614             outBuffer.writeLong(portStat.getRxOverErr().longValue());
615             outBuffer.writeLong(portStat.getRxCrcErr().longValue());
616             outBuffer.writeLong(portStat.getCollisions().longValue());
617             outBuffer.writeInt(portStat.getDurationSec().intValue());
618             outBuffer.writeInt(portStat.getDurationNsec().intValue());
619         }
620     }
621
622     private void serializeTableBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
623         MultipartReplyTableCase tableCase = (MultipartReplyTableCase) body;
624         MultipartReplyTable table = tableCase.getMultipartReplyTable();
625         for (TableStats tableStats : table.getTableStats()) {
626             outBuffer.writeByte(tableStats.getTableId());
627             outBuffer.writeZero(TABLE_PADDING);
628             outBuffer.writeInt(tableStats.getActiveCount().intValue());
629             outBuffer.writeLong(tableStats.getLookupCount().longValue());
630             outBuffer.writeLong(tableStats.getMatchedCount().longValue());
631         }
632     }
633
634     private void serializeAggregateBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
635         MultipartReplyAggregateCase aggregateCase = (MultipartReplyAggregateCase) body;
636         MultipartReplyAggregate aggregate = aggregateCase.getMultipartReplyAggregate();
637         outBuffer.writeLong(aggregate.getPacketCount().longValue());
638         outBuffer.writeLong(aggregate.getByteCount().longValue());
639         outBuffer.writeInt(aggregate.getFlowCount().intValue());
640         outBuffer.writeZero(AGGREGATE_PADDING);
641     }
642
643     private void serializeFlowBody(final MultipartReplyBody body, final ByteBuf outBuffer,
644             final MultipartReplyMessage message) {
645         MultipartReplyFlowCase flowCase = (MultipartReplyFlowCase) body;
646         MultipartReplyFlow flow = flowCase.getMultipartReplyFlow();
647         for (FlowStats flowStats : flow.getFlowStats()) {
648             ByteBuf flowStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
649             flowStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
650             flowStatsBuff.writeByte(new Long(flowStats.getTableId()).byteValue());
651             flowStatsBuff.writeZero(FLOW_STATS_PADDING_1);
652             flowStatsBuff.writeInt(flowStats.getDurationSec().intValue());
653             flowStatsBuff.writeInt(flowStats.getDurationNsec().intValue());
654             flowStatsBuff.writeShort(flowStats.getPriority());
655             flowStatsBuff.writeShort(flowStats.getIdleTimeout());
656             flowStatsBuff.writeShort(flowStats.getHardTimeout());
657             flowStatsBuff.writeZero(FLOW_STATS_PADDING_2);
658             flowStatsBuff.writeLong(flowStats.getCookie().longValue());
659             flowStatsBuff.writeLong(flowStats.getPacketCount().longValue());
660             flowStatsBuff.writeLong(flowStats.getByteCount().longValue());
661             OFSerializer<Match> matchSerializer = registry.<Match, OFSerializer<Match>>getSerializer(
662                     new MessageTypeKey<>(message.getVersion(), Match.class));
663             matchSerializer.serialize(flowStats.getMatch(), flowStatsBuff);
664             ListSerializer.serializeList(flowStats.getInstruction(),
665                     TypeKeyMakerFactory.createInstructionKeyMaker(message.getVersion()), registry, flowStatsBuff);
666
667             flowStatsBuff.setShort(FLOW_STATS_LENGTH_INDEX, flowStatsBuff.readableBytes());
668             outBuffer.writeBytes(flowStatsBuff);
669         }
670     }
671
672     private void serializeDescBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
673         MultipartReplyDescCase descCase = (MultipartReplyDescCase) body;
674         MultipartReplyDesc desc = descCase.getMultipartReplyDesc();
675         write256String(desc.getMfrDesc(), outBuffer);
676         write256String(desc.getHwDesc(), outBuffer);
677         write256String(desc.getSwDesc(), outBuffer);
678         write32String(desc.getSerialNum(), outBuffer);
679         write256String(desc.getDpDesc(), outBuffer);
680     }
681
682     private void write256String(final String toWrite, final ByteBuf outBuffer) {
683         byte[] nameBytes = toWrite.getBytes();
684         if (nameBytes.length < 256) {
685             byte[] nameBytesPadding = new byte[256];
686             int index = 0;
687             for (byte b : nameBytes) {
688                 nameBytesPadding[index] = b;
689                 index++;
690             }
691             for (; index < 256; index++) {
692                 nameBytesPadding[index] = 0x0;
693             }
694             outBuffer.writeBytes(nameBytesPadding);
695         } else {
696             outBuffer.writeBytes(nameBytes);
697         }
698     }
699
700     private void write32String(final String toWrite, final ByteBuf outBuffer) {
701         byte[] nameBytes = toWrite.getBytes();
702         if (nameBytes.length < 32) {
703             byte[] nameBytesPadding = new byte[32];
704             int index = 0;
705             for (byte b : nameBytes) {
706                 nameBytesPadding[index] = b;
707                 index++;
708             }
709             for (; index < 32; index++) {
710                 nameBytesPadding[index] = 0x0;
711             }
712             outBuffer.writeBytes(nameBytesPadding);
713         } else {
714             outBuffer.writeBytes(nameBytes);
715         }
716     }
717
718     private void serializePortDescBody(final MultipartReplyBody body, final ByteBuf outBuffer) {
719         MultipartReplyPortDescCase portCase = (MultipartReplyPortDescCase) body;
720         MultipartReplyPortDesc portDesc = portCase.getMultipartReplyPortDesc();
721         for (Ports port : portDesc.getPorts()) {
722             outBuffer.writeInt(port.getPortNo().intValue()); // Assuming PortNo
723                                                              // = PortId
724             outBuffer.writeZero(PORT_DESC_PADDING_1);
725             outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(port.getHwAddr()));
726             outBuffer.writeZero(PORT_DESC_PADDING_2);
727             writeName(port.getName(), outBuffer);
728             writePortConfig(port.getConfig(), outBuffer);
729             writePortState(port.getState(), outBuffer);
730             writePortFeatures(port.getCurrentFeatures(), outBuffer);
731             writePortFeatures(port.getAdvertisedFeatures(), outBuffer);
732             writePortFeatures(port.getSupportedFeatures(), outBuffer);
733             writePortFeatures(port.getPeerFeatures(), outBuffer);
734             outBuffer.writeInt(port.getCurrSpeed().intValue());
735             outBuffer.writeInt(port.getMaxSpeed().intValue());
736         }
737     }
738
739     private void writeName(final String name, final ByteBuf outBuffer) {
740         byte[] nameBytes = name.getBytes();
741         if (nameBytes.length < 16) {
742             byte[] nameBytesPadding = new byte[16];
743             int index = 0;
744             for (byte b : nameBytes) {
745                 nameBytesPadding[index] = b;
746                 index++;
747             }
748             for (; index < 16; index++) {
749                 nameBytesPadding[index] = 0x0;
750             }
751             outBuffer.writeBytes(nameBytesPadding);
752         } else {
753             outBuffer.writeBytes(nameBytes);
754         }
755
756     }
757
758     private void writePortConfig(final PortConfig config, final ByteBuf outBuffer) {
759         Map<Integer, Boolean> map = new HashMap<>();
760         map.put(0, config.isPortDown());
761         map.put(2, config.isNoRecv());
762         map.put(5, config.isNoFwd());
763         map.put(6, config.isNoPacketIn());
764         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
765         outBuffer.writeInt(bitmap);
766     }
767
768     private void writePortState(final PortState state, final ByteBuf outBuffer) {
769         Map<Integer, Boolean> map = new HashMap<>();
770         map.put(0, state.isLinkDown());
771         map.put(1, state.isBlocked());
772         map.put(2, state.isLive());
773         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
774         outBuffer.writeInt(bitmap);
775     }
776
777     private void writePortFeatures(final PortFeatures features, final ByteBuf outBuffer) {
778         Map<Integer, Boolean> map = new HashMap<>();
779         map.put(0, features.is_10mbHd());
780         map.put(1, features.is_10mbFd());
781         map.put(2, features.is_100mbHd());
782         map.put(3, features.is_100mbFd());
783         map.put(4, features.is_1gbHd());
784         map.put(5, features.is_1gbFd());
785         map.put(6, features.is_10gbFd());
786         map.put(7, features.is_40gbFd());
787         map.put(8, features.is_100gbFd());
788         map.put(9, features.is_1tbFd());
789         map.put(10, features.isOther());
790         map.put(11, features.isCopper());
791         map.put(12, features.isFiber());
792         map.put(13, features.isAutoneg());
793         map.put(14, features.isPause());
794         map.put(15, features.isPauseAsym());
795         int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
796         outBuffer.writeInt(bitmap);
797     }
798 }