/*
* Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.openflowjava.protocol.impl.serialization.factories;
import io.netty.buffer.ByteBuf;
import java.util.List;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector;
import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
import org.opendaylight.openflowjava.protocol.impl.util.ListSerializer;
import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMaker;
import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory;
import org.opendaylight.openflowjava.util.ByteBufUtils;
import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdTableFeatureProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
/**
* Translates MultipartRequest messages.
* @author timotej.kubas
* @author michal.polkorab
*/
public class MultipartRequestInputFactory implements OFSerializer<MultipartRequestInput>, SerializerRegistryInjector {
private static final byte MESSAGE_TYPE = 18;
private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4;
private static final byte INSTRUCTIONS_CODE = 0;
private static final byte INSTRUCTIONS_MISS_CODE = 1;
private static final byte NEXT_TABLE_CODE = 2;
private static final byte NEXT_TABLE_MISS_CODE = 3;
private static final byte WRITE_ACTIONS_CODE = 4;
private static final byte WRITE_ACTIONS_MISS_CODE = 5;
private static final byte APPLY_ACTIONS_CODE = 6;
private static final byte APPLY_ACTIONS_MISS_CODE = 7;
private static final byte MATCH_CODE = 8;
private static final byte WILDCARDS_CODE = 10;
private static final byte WRITE_SETFIELD_CODE = 12;
private static final byte WRITE_SETFIELD_MISS_CODE = 13;
private static final byte APPLY_SETFIELD_CODE = 14;
private static final byte APPLY_SETFIELD_MISS_CODE = 15;
private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3;
private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4;
private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01 = 3;
private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02 = 4;
private static final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4;
private static final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4;
private static final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4;
private static final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4;
private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5;
private SerializerRegistry registry;
@Override
public void serialize(final MultipartRequestInput message, final ByteBuf outBuffer) {
ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH);
outBuffer.writeShort(message.getType().getIntValue());
outBuffer.writeShort(createMultipartRequestFlagsBitmask(message.getFlags()));
outBuffer.writeZero(PADDING_IN_MULTIPART_REQUEST_MESSAGE);
if (message.getMultipartRequestBody() instanceof MultipartRequestDescCase){
serializeDescBody();
} else if (message.getMultipartRequestBody() instanceof MultipartRequestFlowCase) {
serializeFlowBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregateCase) {
serializeAggregateBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestTableCase) {
serializeTableBody();
} else if (message.getMultipartRequestBody() instanceof MultipartRequestPortStatsCase) {
serializePortStatsBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestQueueCase) {
serializeQueueBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupCase) {
serializeeGroupStatsBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupDescCase) {
serializeGroupDescBody();
} else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupFeaturesCase) {
serializeGroupFeaturesBody();
} else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterCase) {
serializeMeterBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterConfigCase) {
serializeMeterConfigBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterFeaturesCase) {
serializeMeterFeaturesBody();
} else if (message.getMultipartRequestBody() instanceof MultipartRequestTableFeaturesCase) {
serializeTableFeaturesBody(message.getMultipartRequestBody(), outBuffer);
} else if (message.getMultipartRequestBody() instanceof MultipartRequestPortDescCase) {
serializePortDescBody();
} else if (message.getMultipartRequestBody() instanceof MultipartRequestExperimenterCase) {
serializeExperimenterBody(message, outBuffer);
}
ByteBufUtils.updateOFHeaderLength(outBuffer);
}
private void serializeExperimenterBody(final MultipartRequestInput message,
final ByteBuf outBuffer) {
MultipartRequestExperimenterCase expCase =
(MultipartRequestExperimenterCase) message.getMultipartRequestBody();
MultipartRequestExperimenter experimenter = expCase.getMultipartRequestExperimenter();
final long expId = experimenter.getExperimenter().getValue().longValue();
final long expType = experimenter.getExpType().longValue();
// write experimenterId and type
outBuffer.writeInt((int) expId);
outBuffer.writeInt((int) expType);
// serialize experimenter data
OFSerializer<ExperimenterDataOfChoice> serializer = registry.getSerializer(
ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey(
EncodeConstants.OF13_VERSION_ID, expId, expType));
serializer.serialize(experimenter.getExperimenterDataOfChoice(), outBuffer);
}
private static int createMultipartRequestFlagsBitmask(final MultipartRequestFlags flags) {
return ByteBufUtils.fillBitMask(0, flags.isOFPMPFREQMORE());
}
private void serializeDescBody() {
// The body of MultiPartRequestDesc is empty
}
private void serializeTableBody() {
// The body of MultiPartTable is empty
}
private void serializeGroupDescBody() {
// The body of MultiPartRequestGroupDesc is empty
}
private void serializeGroupFeaturesBody() {
// The body of MultiPartRequestGroupFeatures is empty
}
private void serializeMeterFeaturesBody() {
// The body of MultiPartMeterFeatures is empty
}
private void serializePortDescBody() {
// The body of MultiPartPortDesc is empty
}
private void serializeFlowBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestFlowCase flowCase = (MultipartRequestFlowCase) multipartRequestBody;
MultipartRequestFlow flow = flowCase.getMultipartRequestFlow();
output.writeByte(flow.getTableId().byteValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01);
output.writeInt(flow.getOutPort().intValue());
output.writeInt(flow.getOutGroup().intValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02);
output.writeLong(flow.getCookie().longValue());
output.writeLong(flow.getCookieMask().longValue());
OFSerializer<Match> serializer = registry.getSerializer(new MessageTypeKey<>(
EncodeConstants.OF13_VERSION_ID, Match.class));
serializer.serialize(flow.getMatch(), output);
}
private void serializeAggregateBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestAggregateCase aggregateCase = (MultipartRequestAggregateCase) multipartRequestBody;
MultipartRequestAggregate aggregate = aggregateCase.getMultipartRequestAggregate();
output.writeByte(aggregate.getTableId().byteValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01);
output.writeInt(aggregate.getOutPort().intValue());
output.writeInt(aggregate.getOutGroup().intValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02);
output.writeLong(aggregate.getCookie().longValue());
output.writeLong(aggregate.getCookieMask().longValue());
OFSerializer<Match> serializer = registry.getSerializer(new MessageTypeKey<>(
EncodeConstants.OF13_VERSION_ID, Match.class));
serializer.serialize(aggregate.getMatch(), output);
}
private static void serializePortStatsBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestPortStatsCase portstatsCase = (MultipartRequestPortStatsCase) multipartRequestBody;
MultipartRequestPortStats portstats = portstatsCase.getMultipartRequestPortStats();
output.writeInt(portstats.getPortNo().intValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY);
}
private static void serializeQueueBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestQueueCase queueCase = (MultipartRequestQueueCase) multipartRequestBody;
MultipartRequestQueue queue = queueCase.getMultipartRequestQueue();
output.writeInt(queue.getPortNo().intValue());
output.writeInt(queue.getQueueId().intValue());
}
private static void serializeeGroupStatsBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestGroupCase groupStatsCase = (MultipartRequestGroupCase) multipartRequestBody;
MultipartRequestGroup groupStats = groupStatsCase.getMultipartRequestGroup();
output.writeInt(groupStats.getGroupId().getValue().intValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY);
}
private static void serializeMeterBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestMeterCase meterCase = (MultipartRequestMeterCase) multipartRequestBody;
MultipartRequestMeter meter = meterCase.getMultipartRequestMeter();
output.writeInt(meter.getMeterId().getValue().intValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_METER_BODY);
}
private static void serializeMeterConfigBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
MultipartRequestMeterConfigCase meterConfigCase = (MultipartRequestMeterConfigCase) multipartRequestBody;
MultipartRequestMeterConfig meterConfig = meterConfigCase.getMultipartRequestMeterConfig();
output.writeInt(meterConfig.getMeterId().getValue().intValue());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY);
}
private void serializeTableFeaturesBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) {
if (multipartRequestBody != null) {
MultipartRequestTableFeaturesCase tableFeaturesCase = (MultipartRequestTableFeaturesCase) multipartRequestBody;
MultipartRequestTableFeatures tableFeatures = tableFeaturesCase.getMultipartRequestTableFeatures();
if(tableFeatures.getTableFeatures() != null) {
for (TableFeatures currTableFeature : tableFeatures.getTableFeatures()) {
int tableFeatureLengthIndex = output.writerIndex();
output.writeShort(EncodeConstants.EMPTY_LENGTH);
output.writeByte(currTableFeature.getTableId());
output.writeZero(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY);
output.writeBytes(currTableFeature.getName().getBytes());
output.writeZero(32 - currTableFeature.getName().getBytes().length);
output.writeLong(currTableFeature.getMetadataMatch().longValue());
output.writeLong(currTableFeature.getMetadataWrite().longValue());
output.writeInt(createTableConfigBitmask(currTableFeature.getConfig()));
output.writeInt(currTableFeature.getMaxEntries().intValue());
writeTableFeatureProperties(output, currTableFeature.getTableFeatureProperties());
output.setShort(tableFeatureLengthIndex, output.writerIndex() - tableFeatureLengthIndex);
}
}
}
}
private void writeTableFeatureProperties(final ByteBuf output, final List<TableFeatureProperties> props) {
if (props != null) {
for (TableFeatureProperties property : props) {
TableFeaturesPropType type = property.getType();
if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)) {
writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_MISS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)) {
writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_MISS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)) {
writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)) {
writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_MISS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)) {
writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_MISS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)) {
writeOxmRelatedTableProperty(output, property, MATCH_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)) {
writeOxmRelatedTableProperty(output, property, WILDCARDS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)) {
writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)) {
writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_MISS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)) {
writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_MISS_CODE);
} else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)) {
writeExperimenterRelatedTableProperty(output, property);
} else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
writeExperimenterRelatedTableProperty(output, property);
}
}
}
}
private void writeInstructionRelatedTableProperty(final ByteBuf output,
final TableFeatureProperties property, final byte code) {
int startIndex = output.writerIndex();
output.writeShort(code);
int lengthIndex = output.writerIndex();
output.writeShort(EncodeConstants.EMPTY_LENGTH);
List<Instruction> instructions = property.
getAugmentation(InstructionRelatedTableFeatureProperty.class).getInstruction();
if (instructions != null) {
TypeKeyMaker<Instruction> keyMaker = TypeKeyMakerFactory
.createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID);
ListSerializer.serializeHeaderList(instructions, keyMaker, registry, output);
}
int length = output.writerIndex() - startIndex;
output.setShort(lengthIndex, length);
output.writeZero(paddingNeeded(length));
}
private static void writeNextTableRelatedTableProperty(final ByteBuf output,
final TableFeatureProperties property, final byte code) {
int startIndex = output.writerIndex();
output.writeShort(code);
int lengthIndex = output.writerIndex();
output.writeShort(EncodeConstants.EMPTY_LENGTH);
List<NextTableIds> nextTableIds = property.
getAugmentation(NextTableRelatedTableFeatureProperty.class).getNextTableIds();
if (nextTableIds != null) {
for (NextTableIds next : nextTableIds) {
output.writeByte(next.getTableId());
}
}
int length = output.writerIndex() - startIndex;
output.setShort(lengthIndex, length);
output.writeZero(paddingNeeded(length));
}
private static int paddingNeeded(final int length) {
int paddingRemainder = length % EncodeConstants.PADDING;
int result = 0;
if (paddingRemainder != 0) {
result = EncodeConstants.PADDING - paddingRemainder;
}
return result;
}
private void writeActionsRelatedTableProperty(final ByteBuf output,
final TableFeatureProperties property, final byte code) {
int startIndex = output.writerIndex();
output.writeShort(code);
int lengthIndex = output.writerIndex();
output.writeShort(EncodeConstants.EMPTY_LENGTH);
List<Action> actions = property.
getAugmentation(ActionRelatedTableFeatureProperty.class).getAction();
if (actions != null) {
TypeKeyMaker<Action> keyMaker = TypeKeyMakerFactory
.createActionKeyMaker(EncodeConstants.OF13_VERSION_ID);
ListSerializer.serializeHeaderList(actions, keyMaker, registry, output);
}
int length = output.writerIndex() - startIndex;
output.setShort(lengthIndex, length);
output.writeZero(paddingNeeded(length));
}
private void writeOxmRelatedTableProperty(final ByteBuf output,
final TableFeatureProperties property, final byte code) {
int startIndex = output.writerIndex();
output.writeShort(code);
int lengthIndex = output.writerIndex();
output.writeShort(EncodeConstants.EMPTY_LENGTH);
List<MatchEntry> entries = property.
getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntry();
if (entries != null) {
TypeKeyMaker<MatchEntry> keyMaker = TypeKeyMakerFactory
.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID);
ListSerializer.serializeHeaderList(entries, keyMaker, registry, output);
}
int length = output.writerIndex() - startIndex;
output.setShort(lengthIndex, length);
output.writeZero(paddingNeeded(length));
}
private void writeExperimenterRelatedTableProperty(final ByteBuf output,
final TableFeatureProperties property) {
long expId = property.getAugmentation(ExperimenterIdTableFeatureProperty.class).getExperimenter().getValue();
OFSerializer<TableFeatureProperties> serializer = registry.getSerializer(
ExperimenterSerializerKeyFactory.createMultipartRequestTFSerializerKey(
EncodeConstants.OF13_VERSION_ID, expId));
serializer.serialize(property, output);
}
private static int createTableConfigBitmask(final TableConfig tableConfig) {
return ByteBufUtils.fillBitMask(3, tableConfig.isOFPTCDEPRECATEDMASK());
}
@Override
public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) {
this.registry = serializerRegistry;
}
}