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