2 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
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
9 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
11 import io.netty.buffer.ByteBuf;
12 import java.math.BigInteger;
13 import java.nio.charset.StandardCharsets;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
18 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
19 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
20 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
21 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker;
22 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory;
23 import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer;
24 import org.opendaylight.openflowjava.util.ByteBufUtils;
25 import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsListBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDropBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemarkBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCaseBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCaseBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCaseBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCaseBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCaseBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCaseBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCaseBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCaseBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCaseBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCaseBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCaseBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregateBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenterBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlowBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStatsBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroupBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStats;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStatsBuilder;
104 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;
105 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.BucketStatsBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDescBuilder;
107 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;
108 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.GroupDescBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeaturesBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeterBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStats;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStatsBuilder;
113 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;
114 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.MeterBandStatsBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfigBuilder;
116 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;
117 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.MeterConfigBuilder;
118 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;
119 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.BandsBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeaturesBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDescBuilder;
122 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;
123 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.PortsBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder;
125 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;
126 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.PortStatsBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueueBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStatsBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTableBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStatsBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeaturesBuilder;
134 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;
135 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.TableFeaturesBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
138 import org.opendaylight.yangtools.yang.common.Uint32;
141 * Translates MultipartReply messages.
143 * @author timotej.kubas
144 * @author michal.polkorab
146 public class MultipartReplyMessageFactory implements OFDeserializer<MultipartReplyMessage>,
147 DeserializerRegistryInjector {
149 private static final byte PADDING_IN_MULTIPART_REPLY_HEADER = 4;
150 private static final int DESC_STR_LEN = 256;
151 private static final int SERIAL_NUM_LEN = 32;
152 private static final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;
153 private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;
154 private static final byte PADDING_IN_AGGREGATE_HEADER = 4;
155 private static final byte PADDING_IN_TABLE_HEADER = 3;
156 private static final byte PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES = 5;
157 private static final byte MAX_TABLE_NAME_LENGTH = 32;
158 private static final byte MULTIPART_REPLY_TABLE_FEATURES_STRUCTURE_LENGTH = 64;
159 private static final byte COMMON_PROPERTY_LENGTH = 4;
160 private static final byte PADDING_IN_PORT_STATS_HEADER = 4;
161 private static final byte PADDING_IN_GROUP_HEADER_01 = 2;
162 private static final byte PADDING_IN_GROUP_HEADER_02 = 4;
163 private static final byte BUCKET_COUNTER_LENGTH = 16;
164 private static final byte GROUP_BODY_LENGTH = 40;
165 private static final byte PADDING_IN_METER_FEATURES_HEADER = 2;
166 private static final byte PADDING_IN_METER_STATS_HEADER = 6;
167 private static final byte METER_BAND_STATS_LENGTH = 16;
168 private static final byte METER_BODY_LENGTH = 40;
169 private static final byte METER_CONFIG_LENGTH = 8;
170 private static final byte PADDING_IN_METER_BAND_DROP_HEADER = 4;
171 private static final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;
172 private static final byte PADDING_IN_PORT_DESC_HEADER_01 = 4;
173 private static final byte PADDING_IN_PORT_DESC_HEADER_02 = 2;
174 private static final int GROUP_TYPES = 4;
175 private static final byte PADDING_IN_GROUP_DESC_HEADER = 1;
176 private static final byte PADDING_IN_BUCKETS_HEADER = 4;
177 private static final byte GROUP_DESC_HEADER_LENGTH = 8;
178 private static final byte BUCKETS_HEADER_LENGTH = 16;
179 private DeserializerRegistry registry;
182 public MultipartReplyMessage deserialize(final ByteBuf rawMessage) {
183 MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();
184 builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
185 builder.setXid(rawMessage.readUnsignedInt());
186 int type = rawMessage.readUnsignedShort();
187 builder.setType(MultipartType.forValue(type));
188 builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));
189 rawMessage.skipBytes(PADDING_IN_MULTIPART_REPLY_HEADER);
191 switch (MultipartType.forValue(type)) {
193 builder.setMultipartReplyBody(setDesc(rawMessage));
196 builder.setMultipartReplyBody(setFlow(rawMessage));
199 builder.setMultipartReplyBody(setAggregate(rawMessage));
202 builder.setMultipartReplyBody(setTable(rawMessage));
205 builder.setMultipartReplyBody(setPortStats(rawMessage));
208 builder.setMultipartReplyBody(setQueue(rawMessage));
211 builder.setMultipartReplyBody(setGroup(rawMessage));
214 builder.setMultipartReplyBody(setGroupDesc(rawMessage));
216 case OFPMPGROUPFEATURES:
217 builder.setMultipartReplyBody(setGroupFeatures(rawMessage));
220 builder.setMultipartReplyBody(setMeter(rawMessage));
222 case OFPMPMETERCONFIG:
223 builder.setMultipartReplyBody(setMeterConfig(rawMessage));
225 case OFPMPMETERFEATURES:
226 builder.setMultipartReplyBody(setMeterFeatures(rawMessage));
228 case OFPMPTABLEFEATURES:
229 builder.setMultipartReplyBody(setTableFeatures(rawMessage));
232 builder.setMultipartReplyBody(setPortDesc(rawMessage));
234 case OFPMPEXPERIMENTER:
235 builder.setMultipartReplyBody(setExperimenter(rawMessage));
241 return builder.build();
244 private static MultipartReplyDescCase setDesc(final ByteBuf input) {
245 final MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder();
246 MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();
247 byte[] mfrDescBytes = new byte[DESC_STR_LEN];
248 input.readBytes(mfrDescBytes);
249 String mfrDesc = new String(mfrDescBytes, StandardCharsets.UTF_8);
250 descBuilder.setMfrDesc(mfrDesc.trim());
251 byte[] hwDescBytes = new byte[DESC_STR_LEN];
252 input.readBytes(hwDescBytes);
253 String hwDesc = new String(hwDescBytes, StandardCharsets.UTF_8);
254 descBuilder.setHwDesc(hwDesc.trim());
255 byte[] swDescBytes = new byte[DESC_STR_LEN];
256 input.readBytes(swDescBytes);
257 String swDesc = new String(swDescBytes, StandardCharsets.UTF_8);
258 descBuilder.setSwDesc(swDesc.trim());
259 byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];
260 input.readBytes(serialNumBytes);
261 String serialNum = new String(serialNumBytes, StandardCharsets.UTF_8);
262 descBuilder.setSerialNum(serialNum.trim());
263 byte[] dpDescBytes = new byte[DESC_STR_LEN];
264 input.readBytes(dpDescBytes);
265 String dpDesc = new String(dpDescBytes, StandardCharsets.UTF_8);
266 descBuilder.setDpDesc(dpDesc.trim());
267 caseBuilder.setMultipartReplyDesc(descBuilder.build());
268 return caseBuilder.build();
271 private MultipartReplyFlowCase setFlow(final ByteBuf input) {
272 MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder();
273 MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();
274 List<FlowStats> flowStatsList = new ArrayList<>();
275 while (input.readableBytes() > 0) {
276 FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();
277 int flowRecordLength = input.readUnsignedShort();
278 ByteBuf subInput = input.readSlice(flowRecordLength - EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
279 flowStatsBuilder.setTableId(subInput.readUnsignedByte());
280 subInput.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);
281 flowStatsBuilder.setDurationSec(subInput.readUnsignedInt());
282 flowStatsBuilder.setDurationNsec(subInput.readUnsignedInt());
283 flowStatsBuilder.setPriority(subInput.readUnsignedShort());
284 flowStatsBuilder.setIdleTimeout(subInput.readUnsignedShort());
285 flowStatsBuilder.setHardTimeout(subInput.readUnsignedShort());
286 flowStatsBuilder.setFlags(createFlowModFlagsFromBitmap(subInput.readUnsignedShort()));
287 subInput.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
288 byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
289 subInput.readBytes(cookie);
290 flowStatsBuilder.setCookie(new BigInteger(1, cookie));
291 byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
292 subInput.readBytes(packetCount);
293 flowStatsBuilder.setPacketCount(new BigInteger(1, packetCount));
294 byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
295 subInput.readBytes(byteCount);
296 flowStatsBuilder.setByteCount(new BigInteger(1, byteCount));
297 OFDeserializer<Match> matchDeserializer = registry.getDeserializer(new MessageCodeKey(
298 EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class));
299 flowStatsBuilder.setMatch(matchDeserializer.deserialize(subInput));
300 CodeKeyMaker keyMaker = CodeKeyMakerFactory
301 .createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
302 List<Instruction> instructions = ListDeserializer.deserializeList(
303 EncodeConstants.OF13_VERSION_ID, subInput.readableBytes(), subInput, keyMaker, registry);
304 flowStatsBuilder.setInstruction(instructions);
305 flowStatsList.add(flowStatsBuilder.build());
307 flowBuilder.setFlowStats(flowStatsList);
308 caseBuilder.setMultipartReplyFlow(flowBuilder.build());
309 return caseBuilder.build();
312 @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
313 private static FlowModFlags createFlowModFlagsFromBitmap(final int input) {
314 final Boolean fmfSENDFLOWREM = (input & 1 << 0) != 0;
315 final Boolean fmfCHECKOVERLAP = (input & 1 << 1) != 0;
316 final Boolean fmfRESETCOUNTS = (input & 1 << 2) != 0;
317 final Boolean fmfNOPKTCOUNTS = (input & 1 << 3) != 0;
318 final Boolean fmfNOBYTCOUNTS = (input & 1 << 4) != 0;
319 return new FlowModFlags(fmfCHECKOVERLAP, fmfNOBYTCOUNTS, fmfNOPKTCOUNTS, fmfRESETCOUNTS, fmfSENDFLOWREM);
322 private static MultipartReplyAggregateCase setAggregate(final ByteBuf input) {
323 final MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder();
324 MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();
325 byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
326 input.readBytes(packetCount);
327 builder.setPacketCount(new BigInteger(1, packetCount));
328 byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
329 input.readBytes(byteCount);
330 builder.setByteCount(new BigInteger(1, byteCount));
331 builder.setFlowCount(input.readUnsignedInt());
332 input.skipBytes(PADDING_IN_AGGREGATE_HEADER);
333 caseBuilder.setMultipartReplyAggregate(builder.build());
334 return caseBuilder.build();
337 private static MultipartReplyTableCase setTable(final ByteBuf input) {
338 MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder();
339 MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();
340 List<TableStats> tableStatsList = new ArrayList<>();
341 while (input.readableBytes() > 0) {
342 TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();
343 tableStatsBuilder.setTableId(input.readUnsignedByte());
344 input.skipBytes(PADDING_IN_TABLE_HEADER);
345 tableStatsBuilder.setActiveCount(input.readUnsignedInt());
346 byte[] lookupCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
347 input.readBytes(lookupCount);
348 tableStatsBuilder.setLookupCount(new BigInteger(1, lookupCount));
349 byte[] matchedCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
350 input.readBytes(matchedCount);
351 tableStatsBuilder.setMatchedCount(new BigInteger(1, matchedCount));
352 tableStatsList.add(tableStatsBuilder.build());
354 builder.setTableStats(tableStatsList);
355 caseBuilder.setMultipartReplyTable(builder.build());
356 return caseBuilder.build();
359 private MultipartReplyTableFeaturesCase setTableFeatures(final ByteBuf input) {
360 MultipartReplyTableFeaturesCaseBuilder caseBuilder = new MultipartReplyTableFeaturesCaseBuilder();
361 MultipartReplyTableFeaturesBuilder builder = new MultipartReplyTableFeaturesBuilder();
362 List<TableFeatures> features = new ArrayList<>();
363 while (input.readableBytes() > 0) {
364 TableFeaturesBuilder featuresBuilder = new TableFeaturesBuilder();
365 final int length = input.readUnsignedShort();
366 featuresBuilder.setTableId(input.readUnsignedByte());
367 input.skipBytes(PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES);
368 featuresBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH));
369 byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
370 input.readBytes(metadataMatch);
371 featuresBuilder.setMetadataMatch(metadataMatch);
372 byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
373 input.readBytes(metadataWrite);
374 featuresBuilder.setMetadataWrite(metadataWrite);
375 featuresBuilder.setConfig(createTableConfig(input.readUnsignedInt()));
376 featuresBuilder.setMaxEntries(input.readUnsignedInt());
377 featuresBuilder.setTableFeatureProperties(createTableFeaturesProperties(input,
378 length - MULTIPART_REPLY_TABLE_FEATURES_STRUCTURE_LENGTH));
379 features.add(featuresBuilder.build());
381 builder.setTableFeatures(features);
382 caseBuilder.setMultipartReplyTableFeatures(builder.build());
383 return caseBuilder.build();
386 private static TableConfig createTableConfig(final long input) {
387 boolean deprecated = (input & 3) != 0;
388 return new TableConfig(deprecated);
391 private List<TableFeatureProperties> createTableFeaturesProperties(final ByteBuf input, final int length) {
392 List<TableFeatureProperties> properties = new ArrayList<>();
393 int tableFeaturesLength = length;
394 while (tableFeaturesLength > 0) {
395 int propStartIndex = input.readerIndex();
396 TableFeaturePropertiesBuilder builder = new TableFeaturePropertiesBuilder();
397 TableFeaturesPropType type = TableFeaturesPropType.forValue(input.readUnsignedShort());
398 builder.setType(type);
399 int propertyLength = input.readUnsignedShort();
400 int paddingRemainder = propertyLength % EncodeConstants.PADDING;
401 tableFeaturesLength -= propertyLength;
402 if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)
403 || type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
404 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
405 List<Instruction> instructions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
406 propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
407 builder.addAugmentation(new InstructionRelatedTableFeaturePropertyBuilder()
408 .setInstruction(instructions)
410 } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)
411 || type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
412 propertyLength -= COMMON_PROPERTY_LENGTH;
413 List<NextTableIds> ids = new ArrayList<>();
414 while (propertyLength > 0) {
415 NextTableIdsBuilder nextTableIdsBuilder = new NextTableIdsBuilder();
416 nextTableIdsBuilder.setTableId(input.readUnsignedByte());
417 ids.add(nextTableIdsBuilder.build());
420 builder.addAugmentation(new NextTableRelatedTableFeaturePropertyBuilder().setNextTableIds(ids).build());
421 } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)
422 || type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)
423 || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)
424 || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
425 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
426 List<Action> actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
427 propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
428 builder.addAugmentation(new ActionRelatedTableFeaturePropertyBuilder().setAction(actions).build());
429 } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)
430 || type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)
431 || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)
432 || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)
433 || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)
434 || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
435 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID);
436 List<MatchEntry> entries = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
437 propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
438 builder.addAugmentation(new OxmRelatedTableFeaturePropertyBuilder().setMatchEntry(entries).build());
439 } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)
440 || type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
441 long expId = input.readUnsignedInt();
442 input.readerIndex(propStartIndex);
443 OFDeserializer<TableFeatureProperties> propDeserializer = registry.getDeserializer(
444 ExperimenterDeserializerKeyFactory.createMultipartReplyTFDeserializerKey(
445 EncodeConstants.OF13_VERSION_ID, expId));
446 TableFeatureProperties expProp = propDeserializer.deserialize(input);
447 properties.add(expProp);
450 if (paddingRemainder != 0) {
451 input.skipBytes(EncodeConstants.PADDING - paddingRemainder);
452 tableFeaturesLength -= EncodeConstants.PADDING - paddingRemainder;
454 properties.add(builder.build());
459 private static MultipartReplyPortStatsCase setPortStats(final ByteBuf input) {
460 MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder();
461 MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();
462 List<PortStats> portStatsList = new ArrayList<>();
463 while (input.readableBytes() > 0) {
464 PortStatsBuilder portStatsBuilder = new PortStatsBuilder();
465 portStatsBuilder.setPortNo(input.readUnsignedInt());
466 input.skipBytes(PADDING_IN_PORT_STATS_HEADER);
467 byte[] rxPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
468 input.readBytes(rxPackets);
469 portStatsBuilder.setRxPackets(new BigInteger(1, rxPackets));
470 byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
471 input.readBytes(txPackets);
472 portStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
473 byte[] rxBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
474 input.readBytes(rxBytes);
475 portStatsBuilder.setRxBytes(new BigInteger(1, rxBytes));
476 byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
477 input.readBytes(txBytes);
478 portStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
479 byte[] rxDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
480 input.readBytes(rxDropped);
481 portStatsBuilder.setRxDropped(new BigInteger(1, rxDropped));
482 byte[] txDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
483 input.readBytes(txDropped);
484 portStatsBuilder.setTxDropped(new BigInteger(1, txDropped));
485 byte[] rxErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
486 input.readBytes(rxErrors);
487 portStatsBuilder.setRxErrors(new BigInteger(1, rxErrors));
488 byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
489 input.readBytes(txErrors);
490 portStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
491 byte[] rxFrameErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
492 input.readBytes(rxFrameErr);
493 portStatsBuilder.setRxFrameErr(new BigInteger(1, rxFrameErr));
494 byte[] rxOverErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
495 input.readBytes(rxOverErr);
496 portStatsBuilder.setRxOverErr(new BigInteger(1, rxOverErr));
497 byte[] rxCrcErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
498 input.readBytes(rxCrcErr);
499 portStatsBuilder.setRxCrcErr(new BigInteger(1, rxCrcErr));
500 byte[] collisions = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
501 input.readBytes(collisions);
502 portStatsBuilder.setCollisions(new BigInteger(1, collisions));
503 portStatsBuilder.setDurationSec(input.readUnsignedInt());
504 portStatsBuilder.setDurationNsec(input.readUnsignedInt());
505 portStatsList.add(portStatsBuilder.build());
507 builder.setPortStats(portStatsList);
508 caseBuilder.setMultipartReplyPortStats(builder.build());
509 return caseBuilder.build();
512 private static MultipartReplyQueueCase setQueue(final ByteBuf input) {
513 MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder();
514 MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();
515 List<QueueStats> queueStatsList = new ArrayList<>();
516 while (input.readableBytes() > 0) {
517 QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();
518 queueStatsBuilder.setPortNo(input.readUnsignedInt());
519 queueStatsBuilder.setQueueId(input.readUnsignedInt());
520 byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
521 input.readBytes(txBytes);
522 queueStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
523 byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
524 input.readBytes(txPackets);
525 queueStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
526 byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
527 input.readBytes(txErrors);
528 queueStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
529 queueStatsBuilder.setDurationSec(input.readUnsignedInt());
530 queueStatsBuilder.setDurationNsec(input.readUnsignedInt());
531 queueStatsList.add(queueStatsBuilder.build());
533 builder.setQueueStats(queueStatsList);
534 caseBuilder.setMultipartReplyQueue(builder.build());
535 return caseBuilder.build();
538 private static MultipartReplyGroupCase setGroup(final ByteBuf input) {
539 MultipartReplyGroupCaseBuilder caseBuilder = new MultipartReplyGroupCaseBuilder();
540 MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder();
541 List<GroupStats> groupStatsList = new ArrayList<>();
542 while (input.readableBytes() > 0) {
543 GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder();
544 final int bodyLength = input.readUnsignedShort();
545 input.skipBytes(PADDING_IN_GROUP_HEADER_01);
546 groupStatsBuilder.setGroupId(new GroupId(input.readUnsignedInt()));
547 groupStatsBuilder.setRefCount(input.readUnsignedInt());
548 input.skipBytes(PADDING_IN_GROUP_HEADER_02);
549 byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
550 input.readBytes(packetCount);
551 groupStatsBuilder.setPacketCount(new BigInteger(1, packetCount));
552 byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
553 input.readBytes(byteCount);
554 groupStatsBuilder.setByteCount(new BigInteger(1, byteCount));
555 groupStatsBuilder.setDurationSec(input.readUnsignedInt());
556 groupStatsBuilder.setDurationNsec(input.readUnsignedInt());
557 int actualLength = GROUP_BODY_LENGTH;
558 List<BucketStats> bucketStatsList = new ArrayList<>();
559 while (actualLength < bodyLength) {
560 BucketStatsBuilder bucketStatsBuilder = new BucketStatsBuilder();
561 byte[] packetCountBucket = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
562 input.readBytes(packetCountBucket);
563 bucketStatsBuilder.setPacketCount(new BigInteger(1, packetCountBucket));
564 byte[] byteCountBucket = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
565 input.readBytes(byteCountBucket);
566 bucketStatsBuilder.setByteCount(new BigInteger(1, byteCountBucket));
567 bucketStatsList.add(bucketStatsBuilder.build());
568 actualLength += BUCKET_COUNTER_LENGTH;
570 groupStatsBuilder.setBucketStats(bucketStatsList);
571 groupStatsList.add(groupStatsBuilder.build());
573 builder.setGroupStats(groupStatsList);
574 caseBuilder.setMultipartReplyGroup(builder.build());
575 return caseBuilder.build();
578 private static MultipartReplyMeterFeaturesCase setMeterFeatures(final ByteBuf input) {
579 final MultipartReplyMeterFeaturesCaseBuilder caseBuilder = new MultipartReplyMeterFeaturesCaseBuilder();
580 MultipartReplyMeterFeaturesBuilder builder = new MultipartReplyMeterFeaturesBuilder();
581 builder.setMaxMeter(input.readUnsignedInt());
582 builder.setBandTypes(createMeterBandsBitmap(input.readUnsignedInt()));
583 builder.setCapabilities(createMeterFlags(input.readUnsignedInt()));
584 builder.setMaxBands(input.readUnsignedByte());
585 builder.setMaxColor(input.readUnsignedByte());
586 input.skipBytes(PADDING_IN_METER_FEATURES_HEADER);
587 caseBuilder.setMultipartReplyMeterFeatures(builder.build());
588 return caseBuilder.build();
591 @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
592 private static MeterFlags createMeterFlags(final long input) {
593 final Boolean mfKBPS = (input & 1 << 0) != 0;
594 final Boolean mfPKTPS = (input & 1 << 1) != 0;
595 final Boolean mfBURST = (input & 1 << 2) != 0;
596 final Boolean mfSTATS = (input & 1 << 3) != 0;
597 return new MeterFlags(mfBURST, mfKBPS, mfPKTPS, mfSTATS);
600 @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
601 private static MeterBandTypeBitmap createMeterBandsBitmap(final long input) {
602 final Boolean mbtDROP = (input & 1 << 1) != 0;
603 final Boolean mbtDSCPREMARK = (input & 1 << 2) != 0;
604 return new MeterBandTypeBitmap(mbtDROP, mbtDSCPREMARK);
607 private static MultipartReplyMeterCase setMeter(final ByteBuf input) {
608 MultipartReplyMeterCaseBuilder caseBuilder = new MultipartReplyMeterCaseBuilder();
609 MultipartReplyMeterBuilder builder = new MultipartReplyMeterBuilder();
610 List<MeterStats> meterStatsList = new ArrayList<>();
611 while (input.readableBytes() > 0) {
612 MeterStatsBuilder meterStatsBuilder = new MeterStatsBuilder();
613 meterStatsBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
614 final int meterStatsBodyLength = input.readUnsignedShort();
615 input.skipBytes(PADDING_IN_METER_STATS_HEADER);
616 meterStatsBuilder.setFlowCount(input.readUnsignedInt());
617 byte[] packetInCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
618 input.readBytes(packetInCount);
619 meterStatsBuilder.setPacketInCount(new BigInteger(1, packetInCount));
620 byte[] byteInCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
621 input.readBytes(byteInCount);
622 meterStatsBuilder.setByteInCount(new BigInteger(1, byteInCount));
623 meterStatsBuilder.setDurationSec(input.readUnsignedInt());
624 meterStatsBuilder.setDurationNsec(input.readUnsignedInt());
625 int actualLength = METER_BODY_LENGTH;
626 List<MeterBandStats> meterBandStatsList = new ArrayList<>();
627 while (actualLength < meterStatsBodyLength) {
628 MeterBandStatsBuilder meterBandStatsBuilder = new MeterBandStatsBuilder();
629 byte[] packetBandCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
630 input.readBytes(packetBandCount);
631 meterBandStatsBuilder.setPacketBandCount(new BigInteger(1, packetBandCount));
632 byte[] byteBandCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
633 input.readBytes(byteBandCount);
634 meterBandStatsBuilder.setByteBandCount(new BigInteger(1, byteBandCount));
635 meterBandStatsList.add(meterBandStatsBuilder.build());
636 actualLength += METER_BAND_STATS_LENGTH;
638 meterStatsBuilder.setMeterBandStats(meterBandStatsList);
639 meterStatsList.add(meterStatsBuilder.build());
641 builder.setMeterStats(meterStatsList);
642 caseBuilder.setMultipartReplyMeter(builder.build());
643 return caseBuilder.build();
646 private MultipartReplyMeterConfigCase setMeterConfig(final ByteBuf input) {
647 MultipartReplyMeterConfigCaseBuilder caseBuilder = new MultipartReplyMeterConfigCaseBuilder();
648 MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder();
649 List<MeterConfig> meterConfigList = new ArrayList<>();
650 while (input.readableBytes() > 0) {
651 MeterConfigBuilder meterConfigBuilder = new MeterConfigBuilder();
652 int meterConfigBodyLength = input.readUnsignedShort();
653 meterConfigBuilder.setFlags(createMeterFlags(input.readUnsignedShort()));
654 meterConfigBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
655 int actualLength = METER_CONFIG_LENGTH;
656 List<Bands> bandsList = new ArrayList<>();
657 while (actualLength < meterConfigBodyLength) {
658 int bandStartIndex = input.readerIndex();
659 BandsBuilder bandsBuilder = new BandsBuilder();
660 int bandType = input.readUnsignedShort();
663 final MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder();
664 MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder();
665 bandDropBuilder.setType(MeterBandType.forValue(bandType));
666 actualLength += input.readUnsignedShort();
667 bandDropBuilder.setRate(input.readUnsignedInt());
668 bandDropBuilder.setBurstSize(input.readUnsignedInt());
669 input.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);
670 bandDropCaseBuilder.setMeterBandDrop(bandDropBuilder.build());
671 bandsBuilder.setMeterBand(bandDropCaseBuilder.build());
674 final MeterBandDscpRemarkCaseBuilder bandDscpRemarkCaseBuilder =
675 new MeterBandDscpRemarkCaseBuilder();
676 MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder();
677 bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType));
678 actualLength += input.readUnsignedShort();
679 bandDscpRemarkBuilder.setRate(input.readUnsignedInt());
680 bandDscpRemarkBuilder.setBurstSize(input.readUnsignedInt());
681 bandDscpRemarkBuilder.setPrecLevel(input.readUnsignedByte());
682 input.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);
683 bandDscpRemarkCaseBuilder.setMeterBandDscpRemark(bandDscpRemarkBuilder.build());
684 bandsBuilder.setMeterBand(bandDscpRemarkCaseBuilder.build());
687 actualLength += input.readUnsignedShort();
688 final long expId = input.getUnsignedInt(input.readerIndex()
689 + 2 * EncodeConstants.SIZE_OF_INT_IN_BYTES);
690 input.readerIndex(bandStartIndex);
691 OFDeserializer<MeterBandExperimenterCase> deserializer = registry.getDeserializer(
692 ExperimenterDeserializerKeyFactory.createMeterBandDeserializerKey(
693 EncodeConstants.OF13_VERSION_ID, expId));
694 bandsBuilder.setMeterBand(deserializer.deserialize(input));
699 bandsList.add(bandsBuilder.build());
701 meterConfigBuilder.setBands(bandsList);
702 meterConfigList.add(meterConfigBuilder.build());
704 builder.setMeterConfig(meterConfigList);
705 caseBuilder.setMultipartReplyMeterConfig(builder.build());
706 return caseBuilder.build();
709 private MultipartReplyExperimenterCase setExperimenter(final ByteBuf input) {
710 final long expId = input.readUnsignedInt();
711 final long expType = input.readUnsignedInt();
713 final OFDeserializer<ExperimenterDataOfChoice> deserializer = registry.getDeserializer(
714 ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey(
715 EncodeConstants.OF13_VERSION_ID, expId, expType));
717 final MultipartReplyExperimenterBuilder mpExperimenterBld = new MultipartReplyExperimenterBuilder()
718 .setExperimenter(new ExperimenterId(expId))
720 .setExperimenterDataOfChoice(deserializer.deserialize(input));
721 final MultipartReplyExperimenterCaseBuilder mpReplyExperimenterCaseBld =
722 new MultipartReplyExperimenterCaseBuilder().setMultipartReplyExperimenter(mpExperimenterBld.build());
723 return mpReplyExperimenterCaseBld.build();
726 private static MultipartReplyPortDescCase setPortDesc(final ByteBuf input) {
727 MultipartReplyPortDescCaseBuilder caseBuilder = new MultipartReplyPortDescCaseBuilder();
728 MultipartReplyPortDescBuilder builder = new MultipartReplyPortDescBuilder();
729 List<Ports> portsList = new ArrayList<>();
730 while (input.readableBytes() > 0) {
731 PortsBuilder portsBuilder = new PortsBuilder();
732 portsBuilder.setPortNo(input.readUnsignedInt());
733 input.skipBytes(PADDING_IN_PORT_DESC_HEADER_01);
734 portsBuilder.setHwAddr(ByteBufUtils.readIetfMacAddress(input));
735 input.skipBytes(PADDING_IN_PORT_DESC_HEADER_02);
736 portsBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, EncodeConstants.MAX_PORT_NAME_LENGTH));
737 portsBuilder.setConfig(createPortConfig(input.readUnsignedInt()));
738 portsBuilder.setState(createPortState(input.readUnsignedInt()));
739 portsBuilder.setCurrentFeatures(createPortFeatures(input.readUnsignedInt()));
740 portsBuilder.setAdvertisedFeatures(createPortFeatures(input.readUnsignedInt()));
741 portsBuilder.setSupportedFeatures(createPortFeatures(input.readUnsignedInt()));
742 portsBuilder.setPeerFeatures(createPortFeatures(input.readUnsignedInt()));
743 portsBuilder.setCurrSpeed(input.readUnsignedInt());
744 portsBuilder.setMaxSpeed(input.readUnsignedInt());
745 portsList.add(portsBuilder.build());
747 builder.setPorts(portsList);
748 caseBuilder.setMultipartReplyPortDesc(builder.build());
749 return caseBuilder.build();
752 private static PortConfig createPortConfig(final long input) {
753 final Boolean pcPortDown = (input & 1 << 0) != 0;
754 final Boolean pcNRecv = (input & 1 << 2) != 0;
755 final Boolean pcNFwd = (input & 1 << 5) != 0;
756 final Boolean pcNPacketIn = (input & 1 << 6) != 0;
757 return new PortConfig(pcNFwd, pcNPacketIn, pcNRecv, pcPortDown);
760 private static PortState createPortState(final long input) {
761 final Boolean psLinkDown = (input & 1 << 0) != 0;
762 final Boolean psBlocked = (input & 1 << 1) != 0;
763 final Boolean psLive = (input & 1 << 2) != 0;
764 return new PortState(psBlocked, psLinkDown, psLive);
767 private static PortFeatures createPortFeatures(final long input) {
768 final Boolean pf10mbHd = (input & 1 << 0) != 0;
769 final Boolean pf10mbFd = (input & 1 << 1) != 0;
770 final Boolean pf100mbHd = (input & 1 << 2) != 0;
771 final Boolean pf100mbFd = (input & 1 << 3) != 0;
772 final Boolean pf1gbHd = (input & 1 << 4) != 0;
773 final Boolean pf1gbFd = (input & 1 << 5) != 0;
774 final Boolean pf10gbFd = (input & 1 << 6) != 0;
775 final Boolean pf40gbFd = (input & 1 << 7) != 0;
776 final Boolean pf100gbFd = (input & 1 << 8) != 0;
777 final Boolean pf1tbFd = (input & 1 << 9) != 0;
778 final Boolean pfOther = (input & 1 << 10) != 0;
779 final Boolean pfCopper = (input & 1 << 11) != 0;
780 final Boolean pfFiber = (input & 1 << 12) != 0;
781 final Boolean pfAutoneg = (input & 1 << 13) != 0;
782 final Boolean pfPause = (input & 1 << 14) != 0;
783 final Boolean pfPauseAsym = (input & 1 << 15) != 0;
784 return new PortFeatures(pf100gbFd, pf100mbFd, pf100mbHd, pf10gbFd, pf10mbFd, pf10mbHd, pf1gbFd,
785 pf1gbHd, pf1tbFd, pf40gbFd, pfAutoneg, pfCopper, pfFiber, pfOther, pfPause, pfPauseAsym);
788 private static MultipartReplyGroupFeaturesCase setGroupFeatures(final ByteBuf rawMessage) {
789 final MultipartReplyGroupFeaturesCaseBuilder caseBuilder = new MultipartReplyGroupFeaturesCaseBuilder();
790 MultipartReplyGroupFeaturesBuilder featuresBuilder = new MultipartReplyGroupFeaturesBuilder();
791 featuresBuilder.setTypes(createGroupType(rawMessage.readUnsignedInt()));
792 featuresBuilder.setCapabilities(createCapabilities(rawMessage.readUnsignedInt()));
793 List<Uint32> maxGroupsList = new ArrayList<>();
794 for (int i = 0; i < GROUP_TYPES; i++) {
795 maxGroupsList.add(Uint32.valueOf(rawMessage.readUnsignedInt()));
797 featuresBuilder.setMaxGroups(maxGroupsList);
798 List<ActionType> actionBitmaps = new ArrayList<>();
799 for (int i = 0; i < GROUP_TYPES; i++) {
800 actionBitmaps.add(createActionBitmap(rawMessage.readUnsignedInt()));
802 featuresBuilder.setActionsBitmap(actionBitmaps);
803 caseBuilder.setMultipartReplyGroupFeatures(featuresBuilder.build());
804 return caseBuilder.build();
807 @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
808 private static ActionType createActionBitmap(final long input) {
809 final Boolean atOutput = (input & 1 << 0) != 0;
810 final Boolean atCopyTTLout = (input & 1 << 11) != 0;
811 final Boolean atCopyTTLin = (input & 1 << 12) != 0;
812 final Boolean atSetMplsTTL = (input & 1 << 15) != 0;
813 final Boolean atDecMplsTTL = (input & 1 << 16) != 0;
814 final Boolean atPushVLAN = (input & 1 << 17) != 0;
815 final Boolean atPopVLAN = (input & 1 << 18) != 0;
816 final Boolean atPushMPLS = (input & 1 << 19) != 0;
817 final Boolean atPopMPLS = (input & 1 << 20) != 0;
818 final Boolean atSetQueue = (input & 1 << 21) != 0;
819 final Boolean atGroup = (input & 1 << 22) != 0;
820 final Boolean atSetNWTTL = (input & 1 << 23) != 0;
821 final Boolean atDecNWTTL = (input & 1 << 24) != 0;
822 final Boolean atSetField = (input & 1 << 25) != 0;
823 final Boolean atPushPBB = (input & 1 << 26) != 0;
824 final Boolean atPopPBB = (input & 1 << 27) != 0;
825 final Boolean atExperimenter = false;
826 return new ActionType(atCopyTTLin, atCopyTTLout, atDecMplsTTL,
827 atDecNWTTL, atExperimenter, atGroup, atOutput, atPopMPLS,
828 atPopPBB, atPopVLAN, atPushMPLS, atPushPBB, atPushVLAN,
829 atSetField, atSetMplsTTL, atSetNWTTL, atSetQueue);
832 private static GroupCapabilities createCapabilities(final long input) {
833 final Boolean gcSelectWeight = (input & 1 << 0) != 0;
834 final Boolean gcSelectLiveness = (input & 1 << 1) != 0;
835 final Boolean gcChaining = (input & 1 << 2) != 0;
836 final Boolean gcChainingChecks = (input & 1 << 3) != 0;
837 return new GroupCapabilities(gcChaining, gcChainingChecks, gcSelectLiveness, gcSelectWeight);
840 private static GroupTypes createGroupType(final long input) {
841 final Boolean gtAll = (input & 1 << 0) != 0;
842 final Boolean gtSelect = (input & 1 << 1) != 0;
843 final Boolean gtIndirect = (input & 1 << 2) != 0;
844 final Boolean gtFF = (input & 1 << 3) != 0;
845 return new GroupTypes(gtAll, gtFF, gtIndirect, gtSelect);
848 private MultipartReplyGroupDescCase setGroupDesc(final ByteBuf input) {
849 MultipartReplyGroupDescCaseBuilder caseBuilder = new MultipartReplyGroupDescCaseBuilder();
850 MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder();
851 List<GroupDesc> groupDescsList = new ArrayList<>();
852 while (input.readableBytes() > 0) {
853 GroupDescBuilder groupDescBuilder = new GroupDescBuilder();
854 final int bodyLength = input.readUnsignedShort();
855 groupDescBuilder.setType(GroupType.forValue(input.readUnsignedByte()));
856 input.skipBytes(PADDING_IN_GROUP_DESC_HEADER);
857 groupDescBuilder.setGroupId(new GroupId(input.readUnsignedInt()));
858 int actualLength = GROUP_DESC_HEADER_LENGTH;
859 List<BucketsList> bucketsList = new ArrayList<>();
860 while (actualLength < bodyLength) {
861 BucketsListBuilder bucketsBuilder = new BucketsListBuilder();
862 final int bucketsLength = input.readUnsignedShort();
863 bucketsBuilder.setWeight(input.readUnsignedShort());
864 bucketsBuilder.setWatchPort(new PortNumber(input.readUnsignedInt()));
865 bucketsBuilder.setWatchGroup(input.readUnsignedInt());
866 input.skipBytes(PADDING_IN_BUCKETS_HEADER);
867 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
868 List<Action> actions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID,
869 bucketsLength - BUCKETS_HEADER_LENGTH, input, keyMaker, registry);
870 bucketsBuilder.setAction(actions);
871 bucketsList.add(bucketsBuilder.build());
872 actualLength += bucketsLength;
874 groupDescBuilder.setBucketsList(bucketsList);
875 groupDescsList.add(groupDescBuilder.build());
877 builder.setGroupDesc(groupDescsList);
878 caseBuilder.setMultipartReplyGroupDesc(builder.build());
879 return caseBuilder.build();
883 public void injectDeserializerRegistry(
884 final DeserializerRegistry deserializerRegistry) {
885 registry = deserializerRegistry;