-/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
-package org.opendaylight.openflowjava.protocol.impl.util;\r
-\r
-import io.netty.buffer.ByteBuf;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10Builder;\r
-\r
-import com.google.common.base.Joiner;\r
-\r
-/**\r
- * Deserializes ofp_match (OpenFlow v1.0) structure\r
- * @author michal.polkorab\r
- */\r
-public abstract class OF10MatchDeserializer {\r
- \r
- private static final byte MAC_ADDRESS_LENGTH = 6;\r
- private static final byte PADDING_IN_MATCH = 1;\r
- private static final byte PADDING_IN_MATCH_2 = 2;\r
- private static final byte GROUPS_IN_IPV4_ADDRESS = 4;\r
-\r
- /**\r
- * Creates ofp_match (OpenFlow v1.0) structure\r
- * @param rawMessage ByteBuf with input data\r
- * @return ofp_match (OpenFlow v1.0)\r
- */\r
- public static MatchV10 createMatchV10(ByteBuf rawMessage) {\r
- MatchV10Builder builder = new MatchV10Builder();\r
- builder.setWildcards(rawMessage.readUnsignedInt());\r
- builder.setInPort(rawMessage.readUnsignedShort());\r
- StringBuffer dlSrc = new StringBuffer();\r
- for(int i = 0; i < MAC_ADDRESS_LENGTH; i++){\r
- short mac = rawMessage.readUnsignedByte();\r
- dlSrc.append(String.format("%02X", mac));\r
- }\r
- builder.setDlSrc(new MacAddress(dlSrc.toString()));\r
- StringBuffer dlDst = new StringBuffer();\r
- for(int i = 0; i < MAC_ADDRESS_LENGTH; i++){\r
- short mac = rawMessage.readUnsignedByte();\r
- dlDst.append(String.format("%02X", mac));\r
- }\r
- builder.setDlDst(new MacAddress(dlDst.toString()));\r
- builder.setDlVlan(rawMessage.readUnsignedShort());\r
- builder.setDlVlanPcp(rawMessage.readUnsignedByte());\r
- rawMessage.skipBytes(PADDING_IN_MATCH);\r
- builder.setDlType(rawMessage.readUnsignedShort());\r
- builder.setNwTos(rawMessage.readUnsignedByte());\r
- builder.setNwProto(rawMessage.readUnsignedByte());\r
- rawMessage.skipBytes(PADDING_IN_MATCH_2);\r
- List<String> srcGroups = new ArrayList<>();\r
- for (int i = 0; i < GROUPS_IN_IPV4_ADDRESS; i++) {\r
- srcGroups.add(Short.toString(rawMessage.readUnsignedByte()));\r
- }\r
- Joiner joiner = Joiner.on(".");\r
- builder.setNwSrc(new Ipv4Address(joiner.join(srcGroups)));\r
- List<String> dstGroups = new ArrayList<>();\r
- for (int i = 0; i < GROUPS_IN_IPV4_ADDRESS; i++) {\r
- dstGroups.add(Short.toString(rawMessage.readUnsignedByte()));\r
- }\r
- builder.setNwSrc(new Ipv4Address(joiner.join(dstGroups)));\r
- builder.setTpSrc(rawMessage.readUnsignedShort());\r
- builder.setTpDst(rawMessage.readUnsignedShort());\r
- return builder.build();\r
- }\r
- \r
-}\r
+/*
+ * 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.util;
+
+import io.netty.buffer.ByteBuf;
+
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
+
+/**
+ * Deserializes ofp_match (OpenFlow v1.0) structure
+ * @author michal.polkorab
+ */
+public class OF10MatchDeserializer implements OFDeserializer<MatchV10> {
+
+ private static final byte PADDING_IN_MATCH = 1;
+ private static final byte PADDING_IN_MATCH_2 = 2;
+ private static final byte NW_SRC_BITS = 6;
+ private static final byte NW_SRC_SHIFT = 8;
+ private static final int NW_SRC_MASK = ((1 << NW_SRC_BITS) - 1) << NW_SRC_SHIFT;
+ private static final byte NW_DST_BITS = 6;
+ private static final byte NW_DST_SHIFT = 14;
+ private static final int NW_DST_MASK = ((1 << NW_DST_BITS) - 1) << NW_DST_SHIFT;
+
+ @Override
+ public MatchV10 deserialize(final ByteBuf input) {
+ MatchV10Builder builder = new MatchV10Builder();
+ long wildcards = input.readUnsignedInt();
+ builder.setWildcards(createWildcards(wildcards));
+ builder.setNwSrcMask(decodeNwSrcMask(wildcards));
+ builder.setNwDstMask(decodeNwDstMask(wildcards));
+ builder.setInPort(input.readUnsignedShort());
+ byte[] dlSrc = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
+ input.readBytes(dlSrc);
+ builder.setDlSrc(new MacAddress(ByteBufUtils.macAddressToString(dlSrc)));
+ byte[] dlDst = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
+ input.readBytes(dlDst);
+ builder.setDlDst(new MacAddress(ByteBufUtils.macAddressToString(dlDst)));
+
+ builder.setDlVlan(input.readUnsignedShort());
+ builder.setDlVlanPcp(input.readUnsignedByte());
+ input.skipBytes(PADDING_IN_MATCH);
+ builder.setDlType(input.readUnsignedShort());
+ builder.setNwTos(input.readUnsignedByte());
+ builder.setNwProto(input.readUnsignedByte());
+ input.skipBytes(PADDING_IN_MATCH_2);
+ builder.setNwSrc(new Ipv4Address(ByteBufUtils.readIpv4Address(input)));
+ builder.setNwDst(new Ipv4Address(ByteBufUtils.readIpv4Address(input)));
+ builder.setTpSrc(input.readUnsignedShort());
+ builder.setTpDst(input.readUnsignedShort());
+ return builder.build();
+ }
+
+ /**
+ * Decodes FlowWildcards
+ * @param input input ByteBuf
+ * @return decoded FlowWildcardsV10
+ */
+ public static FlowWildcardsV10 createWildcards(final long input) {
+ boolean inPort = (input & (1 << 0)) != 0;
+ boolean dlVLAN = (input & (1 << 1)) != 0;
+ boolean dlSrc = (input & (1 << 2)) != 0;
+ boolean dlDst = (input & (1 << 3)) != 0;
+ boolean dLType = (input & (1 << 4)) != 0;
+ boolean nwProto = (input & (1 << 5)) != 0;
+ boolean tpSrc = (input & (1 << 6)) != 0;
+ boolean tpDst = (input & (1 << 7)) != 0;
+ boolean dlVLANpcp = (input & (1 << 20)) != 0;
+ boolean nwTos = (input & (1 << 21)) != 0;
+ return new FlowWildcardsV10(dlDst, dlSrc, dLType, dlVLAN,
+ dlVLANpcp, inPort, nwProto, nwTos, tpDst, tpSrc);
+ }
+
+ /**
+ * Decodes NwSrcMask from FlowWildcards (represented as uint32)
+ * @param input binary FlowWildcards
+ * @return decoded NwSrcMask
+ */
+ public static short decodeNwSrcMask(final long input) {
+ return (short) Math.max(32 - ((input & NW_SRC_MASK) >> NW_SRC_SHIFT), 0);
+ }
+
+ /**
+ * Decodes NwDstMask from FlowWildcards (represented as uint32)
+ * @param input binary FlowWildcards
+ * @return decoded NwDstMask
+ */
+ public static short decodeNwDstMask(final long input) {
+ return (short) Math.max(32 - ((input & NW_DST_MASK) >> NW_DST_SHIFT), 0);
+ }
+}