X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflow-protocol-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowjava%2Fprotocol%2Fimpl%2Fserialization%2Ffactories%2FMultipartRequestInputFactory.java;h=b374bef5cf257e231c1819878aaff6d253bebf06;hb=29a2a074c78708f6d18583779ece96bb6573f0c6;hp=5b37619ce024478aff2eb587ed6b9d2fb09b7da3;hpb=9854b91fc508a5679c742451ee2b05d3d9e9d140;p=openflowjava.git diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java index 5b37619c..b374bef5 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java @@ -1,510 +1,433 @@ -/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */ -package org.opendaylight.openflowjava.protocol.impl.serialization.factories; - -import io.netty.buffer.ByteBuf; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer; -import org.opendaylight.openflowjava.protocol.impl.util.ActionsSerializer; -import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils; -import org.opendaylight.openflowjava.protocol.impl.util.InstructionsSerializer; -import org.opendaylight.openflowjava.protocol.impl.util.MatchSerializer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeatureProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions; -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.MultipartType; -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.rev130731.oxm.fields.MatchEntries; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; -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.MultipartRequestAggregate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroup; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfig; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDesc; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStats; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueue; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features.TableFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties; - -/** - * Translates MultipartRequest messages - * @author timotej.kubas - * @author michal.polkorab - */ -public class MultipartRequestInputFactory implements OFSerializer { - private static final byte MESSAGE_TYPE = 18; - private static final int MESSAGE_LENGTH = 16; - private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4; - private static final byte TABLE_FEAT_HEADER_LENGTH = 4; - private static MultipartRequestInputFactory instance; - - private MultipartRequestInputFactory() { - // singleton - } - - /** - * @return singleton factory - */ - public static synchronized MultipartRequestInputFactory getInstance() { - if (instance == null) { - instance = new MultipartRequestInputFactory(); - } - return instance; - } - - @Override - public void messageToBuffer(short version, ByteBuf out, - MultipartRequestInput message) { - ByteBufUtils.writeOFHeader(instance, message, out); - out.writeShort(message.getType().getIntValue()); - out.writeShort(createMultipartRequestFlagsBitmask(message.getFlags())); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_MESSAGE, out); - - if (message.getMultipartRequestBody() instanceof MultipartRequestDesc ){ - encodeDescBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestFlow) { - encodeFlowBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregate) { - encodeAggregateBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestTable) { - encodeTableBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortStats) { - encodePortStatsBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestQueue) { - encodeQueueBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroup) { - encodeGroupStatsBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupDesc) { - encodeGroupDescBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupFeatures) { - encodeGroupFeaturesBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeter) { - encodeMeterBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterConfig) { - encodeMeterConfigBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterFeatures) { - encodeMeterFeaturesBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestTableFeatures) { - encodeTableFeaturesBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortDesc) { - encodePortDescBody(message.getMultipartRequestBody(), out); - } else if (message.getMultipartRequestBody() instanceof MultipartRequestExperimenter) { - encodeExperimenterBody(message.getMultipartRequestBody(), out); - } - } - - @Override - public int computeLength(MultipartRequestInput message) { - return MESSAGE_LENGTH + computeBodyLength(message); - } - @Override - public byte getMessageType() { - return MESSAGE_TYPE; - } - - /** - * - * @param message - * @return length of MultipartRequestMessage - */ - public int computeBodyLength(MultipartRequestInput message) { - int length = 0; - MultipartType type = message.getType(); - if (type.equals(MultipartType.OFPMPFLOW)) { - final byte FLOW_BODY_LENGTH = 32; - MultipartRequestFlow body = (MultipartRequestFlow) message.getMultipartRequestBody(); - length += FLOW_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch()); - } else if (type.equals(MultipartType.OFPMPAGGREGATE)) { - final byte AGGREGATE_BODY_LENGTH = 32; - MultipartRequestAggregate body = (MultipartRequestAggregate) message.getMultipartRequestBody(); - length += AGGREGATE_BODY_LENGTH + MatchSerializer.computeMatchLength(body.getMatch()); - } else if (type.equals(MultipartType.OFPMPPORTSTATS)) { - final byte PORT_STATS_BODY_LENGTH = 8; - length += PORT_STATS_BODY_LENGTH; - } else if (type.equals(MultipartType.OFPMPQUEUE)) { - final byte QUEUE_BODY_LENGTH = 8; - length += QUEUE_BODY_LENGTH; - } else if (type.equals(MultipartType.OFPMPGROUP)) { - final byte GROUP_BODY_LENGTH = 8; - length += GROUP_BODY_LENGTH; - } else if (type.equals(MultipartType.OFPMPMETER)) { - final byte METER_BODY_LENGTH = 8; - length += METER_BODY_LENGTH; - } else if (type.equals(MultipartType.OFPMPMETERCONFIG)) { - final byte METER_CONFIG_BODY_LENGTH = 8; - length += METER_CONFIG_BODY_LENGTH; - } else if (type.equals(MultipartType.OFPMPTABLEFEATURES)) { - MultipartRequestTableFeatures body = (MultipartRequestTableFeatures) message.getMultipartRequestBody(); - length += computeTableFeaturesLength(body); - } else if (type.equals(MultipartType.OFPMPEXPERIMENTER)) { - final byte EXPERIMENTER_BODY_LENGTH = 8; - MultipartRequestExperimenter body = (MultipartRequestExperimenter) message.getMultipartRequestBody(); - length += EXPERIMENTER_BODY_LENGTH; - if (body.getData() != null) { - length += body.getData().length; - } - } - return length; - } - - private static int computeTableFeaturesLength(MultipartRequestTableFeatures body) { - final byte TABLE_FEATURES_LENGTH = 64; - final byte STRUCTURE_HEADER_LENGTH = 4; - int length = 0; - if (body != null) { - List tableFeatures = body.getTableFeatures(); - for (TableFeatures feature : tableFeatures) { - length += TABLE_FEATURES_LENGTH; - List featureProperties = feature.getTableFeatureProperties(); - if (featureProperties != null) { - for (TableFeatureProperties featProp : featureProperties) { - length += TABLE_FEAT_HEADER_LENGTH; - if (featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class) != null) { - InstructionRelatedTableFeatureProperty property = - featProp.getAugmentation(InstructionRelatedTableFeatureProperty.class); - length += property.getInstructions().size() * STRUCTURE_HEADER_LENGTH; - } else if (featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class) != null) { - NextTableRelatedTableFeatureProperty property = - featProp.getAugmentation(NextTableRelatedTableFeatureProperty.class); - length += property.getNextTableIds().size(); - } else if (featProp.getAugmentation(ActionRelatedTableFeatureProperty.class) != null) { - ActionRelatedTableFeatureProperty property = - featProp.getAugmentation(ActionRelatedTableFeatureProperty.class); - length += property.getActionsList().size() * STRUCTURE_HEADER_LENGTH; - } else if (featProp.getAugmentation(OxmRelatedTableFeatureProperty.class) != null) { - OxmRelatedTableFeatureProperty property = - featProp.getAugmentation(OxmRelatedTableFeatureProperty.class); - length += property.getMatchEntries().size() * STRUCTURE_HEADER_LENGTH; - } else if (featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class) != null) { - ExperimenterRelatedTableFeatureProperty property = - featProp.getAugmentation(ExperimenterRelatedTableFeatureProperty.class); - length += 2 * (Integer.SIZE / Byte.SIZE); - if (property.getData() != null) { - length += property.getData().length; - } - } - } - } - } - } - return length; - } - - private static int createMultipartRequestFlagsBitmask(MultipartRequestFlags flags) { - int multipartRequestFlagsBitmask = 0; - Map multipartRequestFlagsMap = new HashMap<>(); - multipartRequestFlagsMap.put(0, flags.isOFPMPFREQMORE()); - - multipartRequestFlagsBitmask = ByteBufUtils.fillBitMaskFromMap(multipartRequestFlagsMap); - return multipartRequestFlagsBitmask; - } - - /** - * @param multipartRequestBody - * @param output - */ - private void encodeDescBody(MultipartRequestBody multipartRequestBody, - ByteBuf output) { - // The body of MultiPartRequestDesc is empty - } - - /** - * @param multipartRequestBody - * @param out - */ - private void encodeTableBody(MultipartRequestBody multipartRequestBody, - ByteBuf out) { - // The body of MultiPartTable is empty - } - - /** - * @param multipartRequestBody - * @param out - */ - private void encodeGroupDescBody(MultipartRequestBody multipartRequestBody, - ByteBuf out) { - // The body of MultiPartRequestGroupDesc is empty - } - - /** - * @param multipartRequestBody - * @param out - */ - private void encodeGroupFeaturesBody( - MultipartRequestBody multipartRequestBody, ByteBuf out) { - // The body of MultiPartRequestGroupFeatures is empty - } - - /** - * @param multipartRequestBody - * @param out - */ - private void encodeMeterFeaturesBody( - MultipartRequestBody multipartRequestBody, ByteBuf out) { - // The body of MultiPartMeterFeatures is empty - } - - /** - * @param multipartRequestBody - * @param out - */ - private void encodePortDescBody(MultipartRequestBody multipartRequestBody, - ByteBuf out) { - // The body of MultiPartPortDesc is empty - } - - private static void encodeFlowBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3; - final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4; - MultipartRequestFlow flow = (MultipartRequestFlow) multipartRequestBody; - output.writeByte(flow.getTableId().byteValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01, output); - output.writeInt(flow.getOutPort().intValue()); - output.writeInt(flow.getOutGroup().intValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02, output); - output.writeLong(flow.getCookie().longValue()); - output.writeLong(flow.getCookieMask().longValue()); - MatchSerializer.encodeMatch(flow.getMatch(), output); - } - - private static void encodeAggregateBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01 = 3; - final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02 = 4; - MultipartRequestAggregate aggregate = (MultipartRequestAggregate) multipartRequestBody; - output.writeByte(aggregate.getTableId().byteValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01, output); - output.writeInt(aggregate.getOutPort().intValue()); - output.writeInt(aggregate.getOutGroup().intValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02, output); - output.writeLong(aggregate.getCookie().longValue()); - output.writeLong(aggregate.getCookieMask().longValue()); - MatchSerializer.encodeMatch(aggregate.getMatch(), output); - } - - private static void encodePortStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4; - MultipartRequestPortStats portstats = (MultipartRequestPortStats) multipartRequestBody; - output.writeInt(portstats.getPortNo().intValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY, output); - } - - private static void encodeQueueBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - MultipartRequestQueue queue = (MultipartRequestQueue) multipartRequestBody; - output.writeInt(queue.getPortNo().intValue()); - output.writeInt(queue.getQueueId().intValue()); - } - - private static void encodeGroupStatsBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4; - MultipartRequestGroup groupStats = (MultipartRequestGroup) multipartRequestBody; - output.writeInt(groupStats.getGroupId().intValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY, output); - } - - private static void encodeMeterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4; - MultipartRequestMeter meter = (MultipartRequestMeter) multipartRequestBody; - output.writeInt(meter.getMeterId().intValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_BODY, output); - } - - private static void encodeMeterConfigBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4; - MultipartRequestMeterConfig meterConfig = (MultipartRequestMeterConfig) multipartRequestBody; - output.writeInt(meterConfig.getMeterId().intValue()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY, output); - } - - private static void encodeExperimenterBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - MultipartRequestExperimenter experimenter = (MultipartRequestExperimenter) multipartRequestBody; - output.writeInt(experimenter.getExperimenter().intValue()); - output.writeInt(experimenter.getExpType().intValue()); - byte[] data = experimenter.getData(); - if (data != null) { - output.writeBytes(data); - } - } - - private static void encodeTableFeaturesBody(MultipartRequestBody multipartRequestBody, ByteBuf output) { - if (multipartRequestBody != null) { - MultipartRequestTableFeatures tableFeatures = (MultipartRequestTableFeatures) multipartRequestBody; - for (TableFeatures currTableFeature : tableFeatures.getTableFeatures()) { - final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5; - output.writeByte(currTableFeature.getTableId()); - ByteBufUtils.padBuffer(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY, output); - output.writeBytes(currTableFeature.getName().getBytes()); - ByteBufUtils.padBuffer((32 - currTableFeature.getName().getBytes().length), output); - output.writeLong(currTableFeature.getMetadataMatch().longValue()); - output.writeLong(currTableFeature.getMetadataWrite().longValue()); - output.writeInt(createTableConfigBitmask(currTableFeature.getConfig())); - output.writeInt(currTableFeature.getMaxEntries().intValue()); - writeTableFeatureProperties(output, currTableFeature.getTableFeatureProperties()); - } - } - } - - private static void writeTableFeatureProperties(ByteBuf output, List props) { - if (props != null) { - for (TableFeatureProperties property : props) { - TableFeaturesPropType type = property.getType(); - if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)) { - final byte INSTRUCTIONS_CODE = 0; - writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) { - final byte INSTRUCTIONS_MISS_CODE = 1; - writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_MISS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)) { - final byte NEXT_TABLE_CODE = 2; - writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) { - final byte NEXT_TABLE_MISS_CODE = 3; - writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_MISS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)) { - final byte WRITE_ACTIONS_CODE = 4; - writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)) { - final byte WRITE_ACTIONS_MISS_CODE = 5; - writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_MISS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)) { - final byte APPLY_ACTIONS_CODE = 6; - writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) { - final byte APPLY_ACTIONS_MISS_CODE = 7; - writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_MISS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)) { - final byte MATCH_CODE = 8; - writeOxmRelatedTableProperty(output, property, MATCH_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)) { - final byte WILDCARDS_CODE = 10; - writeOxmRelatedTableProperty(output, property, WILDCARDS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)) { - final byte WRITE_SETFIELD_CODE = 12; - writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)) { - final byte WRITE_SETFIELD_MISS_CODE = 13; - writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_MISS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)) { - final byte APPLY_SETFIELD_CODE = 14; - writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) { - final byte APPLY_SETFIELD_MISS_CODE = 15; - writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_MISS_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)) { - final int EXPERIMENTER_CODE = 65534; // 0xFFFE - writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_CODE); - } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) { - final int EXPERIMENTER_MISS_CODE = 65535; // 0xFFFF - writeExperimenterRelatedTableProperty(output, property, EXPERIMENTER_MISS_CODE); - } - } - } - } - - private static void writeInstructionRelatedTableProperty(ByteBuf output, - TableFeatureProperties property, byte code) { - output.writeShort(code); - List instructions = property. - getAugmentation(InstructionRelatedTableFeatureProperty.class).getInstructions(); - int length = TABLE_FEAT_HEADER_LENGTH; - if (instructions != null) { - output.writeShort(InstructionsSerializer.computeInstructionsLength(instructions) - + TABLE_FEAT_HEADER_LENGTH); - InstructionsSerializer.encodeInstructions(instructions, output); - } else { - output.writeShort(length); - } - } - - private static void writeNextTableRelatedTableProperty(ByteBuf output, - TableFeatureProperties property, byte code) { - output.writeShort(code); - List nextTableIds = property. - getAugmentation(NextTableRelatedTableFeatureProperty.class).getNextTableIds(); - int length = TABLE_FEAT_HEADER_LENGTH; - if (nextTableIds != null) { - output.writeShort(length + nextTableIds.size()); - for (NextTableIds next : nextTableIds) { - output.writeByte(next.getTableId()); - } - } else { - output.writeShort(length); - } - } - - private static void writeActionsRelatedTableProperty(ByteBuf output, - TableFeatureProperties property, byte code) { - output.writeShort(code); - List actions = property. - getAugmentation(ActionRelatedTableFeatureProperty.class).getActionsList(); - int length = TABLE_FEAT_HEADER_LENGTH; - if (actions != null) { - output.writeShort(ActionsSerializer.computeLengthOfActions(actions) - + TABLE_FEAT_HEADER_LENGTH); - ActionsSerializer.encodeActions(actions, output); - } else { - output.writeShort(length); - } - } - - private static void writeOxmRelatedTableProperty(ByteBuf output, - TableFeatureProperties property, byte code) { - output.writeShort(code); - List entries = property. - getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntries(); - int length = TABLE_FEAT_HEADER_LENGTH; - if (entries != null) { - output.writeShort(MatchSerializer.computeMatchEntriesLength(entries) - + TABLE_FEAT_HEADER_LENGTH); - MatchSerializer.encodeMatchEntries(entries, output); - } else { - output.writeShort(length); - } - } - - private static void writeExperimenterRelatedTableProperty(ByteBuf output, - TableFeatureProperties property, int code) { - output.writeShort(code); - ExperimenterRelatedTableFeatureProperty exp = property. - getAugmentation(ExperimenterRelatedTableFeatureProperty.class); - byte[] data = exp.getData(); - int length = TABLE_FEAT_HEADER_LENGTH + 2 * (Integer.SIZE / Byte.SIZE); - if (data != null) { - output.writeShort(length + data.length); - output.writeInt(exp.getExperimenter().intValue()); - output.writeInt(exp.getExpType().intValue()); - output.writeBytes(data); - } else { - output.writeShort(length); - output.writeInt(exp.getExperimenter().intValue()); - output.writeInt(exp.getExpType().intValue()); - } - } - - private static int createTableConfigBitmask(TableConfig tableConfig) { - int tableConfigBitmask = 0; - Map tableConfigMap = new HashMap<>(); - tableConfigMap.put(3, tableConfig.isOFPTCDEPRECATEDMASK()); - - tableConfigBitmask = ByteBufUtils.fillBitMaskFromMap(tableConfigMap); - return tableConfigBitmask; - } -} +/* + * 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.ExperimenterIdMultipartRequest; +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.rev130731.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.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, 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(); + long expId = experimenter.getAugmentation(ExperimenterIdMultipartRequest.class).getExperimenter().getValue(); + OFSerializer serializer = registry.getSerializer( + ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( + EncodeConstants.OF13_VERSION_ID, expId)); + serializer.serialize(expCase, outBuffer); + } + + private static int createMultipartRequestFlagsBitmask(final MultipartRequestFlags flags) { + return ByteBufUtils.fillBitMask(0, flags.isOFPMPFREQMORE()); + } + + /** + * @param multipartRequestBody + * @param output + */ + private void serializeDescBody() { + // The body of MultiPartRequestDesc is empty + } + + /** + * @param multipartRequestBody + * @param out + */ + private void serializeTableBody() { + // The body of MultiPartTable is empty + } + + /** + * @param multipartRequestBody + * @param out + */ + private void serializeGroupDescBody() { + // The body of MultiPartRequestGroupDesc is empty + } + + /** + * @param multipartRequestBody + * @param out + */ + private void serializeGroupFeaturesBody() { + // The body of MultiPartRequestGroupFeatures is empty + } + + /** + * @param multipartRequestBody + * @param out + */ + private void serializeMeterFeaturesBody() { + // The body of MultiPartMeterFeatures is empty + } + + /** + * @param multipartRequestBody + * @param out + */ + 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 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 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 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 instructions = property. + getAugmentation(InstructionRelatedTableFeatureProperty.class).getInstruction(); + if (instructions != null) { + TypeKeyMaker 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 = 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 actions = property. + getAugmentation(ActionRelatedTableFeatureProperty.class).getAction(); + if (actions != null) { + TypeKeyMaker 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 entries = property. + getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntry(); + if (entries != null) { + TypeKeyMaker 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 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; + } +}