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