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