Merge "OPNFLWPLUG-1062 Include additional LLDP fields in liblldp"
[openflowplugin.git] / libraries / liblldp / src / main / java / org / opendaylight / openflowplugin / libraries / liblldp / LLDPTLV.java
index a030d1b59bb174b3e2a0d4b40dfe57a93780633b..2263a5f749ca40bb6947482bf544a5cd64a60055 100644 (file)
@@ -8,54 +8,52 @@
 
 package org.opendaylight.openflowplugin.libraries.liblldp;
 
-import org.apache.commons.lang3.ArrayUtils;
-import org.slf4j.LoggerFactory;
-
-import org.slf4j.Logger;
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.tuple.MutablePair;
 import org.apache.commons.lang3.tuple.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * Class that represents the LLDPTLV objects
+ * Class that represents the LLDPTLV objects.
  */
-
+@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
 public class LLDPTLV extends Packet {
+    private static final Logger LOG = LoggerFactory.getLogger(LLDPTLV.class);
     private static final String TYPE = "Type";
     private static final String LENGTH = "Length";
     private static final String VALUE = "Value";
-    private static final int LLDPTLVFields = 3;
+    private static final int LLDPTLV_FIELDS = 3;
 
-    /** OpenFlow OUI */
-    public static final byte[] OFOUI = new byte[] { (byte) 0x00, (byte) 0x26,
-        (byte) 0xe1 };
+    /** OpenFlow OUI. */
+    static final byte[] OFOUI = new byte[] { (byte) 0x00, (byte) 0x26, (byte) 0xe1 };
 
-    /** Length of Organizationally defined subtype field of TLV in bytes   */
-    private static final byte customTlvSubTypeLength = (byte)1;
+    /** Length of Organizationally defined subtype field of TLV in bytes.   */
+    private static final byte CUSTOM_TLV_SUB_TYPE_LENGTH = (byte)1;
 
-    /** OpenFlow subtype: nodeConnectorId of source */
-    public static final byte[] CUSTOM_TLV_SUB_TYPE_NODE_CONNECTOR_ID = new byte[] { 0 };
+    /** OpenFlow subtype: nodeConnectorId of source. */
+    private static final byte[] CUSTOM_TLV_SUB_TYPE_NODE_CONNECTOR_ID = new byte[] { 0 };
 
-    /** OpenFlow subtype: custom sec = hash code of verification of origin of LLDP */
-    public static final byte[] CUSTOM_TLV_SUB_TYPE_CUSTOM_SEC = new byte[] { 1 };
+    /** OpenFlow subtype: custom sec = hash code of verification of origin of LLDP. */
+    private static final byte[] CUSTOM_TLV_SUB_TYPE_CUSTOM_SEC = new byte[] { 1 };
 
-    public static final int customTlvOffset = OFOUI.length + customTlvSubTypeLength;
-    public static final byte chassisIDSubType[] = new byte[] { 4 }; // MAC address for the system
-    public static final byte portIDSubType[] = new byte[] { 7 }; // locally assigned
-
-    private static final Logger LOG = LoggerFactory.getLogger(LLDPTLV.class);
+    private static final int CUSTOM_TLV_OFFSET = OFOUI.length + CUSTOM_TLV_SUB_TYPE_LENGTH;
+    private static final byte[] CHASSISID_SUB_TYPE = new byte[] { 4 }; // MAC address for the system
+    private static final byte[] PORTID_SUB_TYPE = new byte[] { 7 }; // locally assigned
 
     public enum TLVType {
         Unknown((byte) 0), ChassisID((byte) 1), PortID((byte) 2), TTL((byte) 3), PortDesc(
-                (byte) 4), SystemName((byte) 5), SystemDesc((byte) 6), Custom(
-                        (byte) 127);
+                (byte) 4), SystemName((byte) 5), SystemDesc((byte) 6), SystemCapabilities((byte) 7),
+                ManagementAddress((byte) 8), Custom((byte) 127);
 
-        private byte value;
+        private final byte value;
 
         TLVType(final byte value) {
             this.value = value;
@@ -66,31 +64,28 @@ public class LLDPTLV extends Packet {
         }
     }
 
-    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
-        private static final long serialVersionUID = 1L;
+    private static final Map<String, Pair<Integer, Integer>> FIELD_COORDINATES = new LinkedHashMap<>();
 
-        {
-            put(TYPE, new MutablePair<>(0, 7));
-            put(LENGTH, new MutablePair<>(7, 9));
-            put(VALUE, new MutablePair<>(16, 0));
-        }
-    };
+    static {
+        FIELD_COORDINATES.put(TYPE, new MutablePair<>(0, 7));
+        FIELD_COORDINATES.put(LENGTH, new MutablePair<>(7, 9));
+        FIELD_COORDINATES.put(VALUE, new MutablePair<>(16, 0));
+    }
 
     protected Map<String, byte[]> fieldValues;
 
     /**
-     * Default constructor that creates and sets the hash map values and sets
-     * the payload to null
+     * Default constructor that creates and sets the hash map values and sets the payload to null.
      */
     public LLDPTLV() {
         payload = null;
-        fieldValues = new HashMap<>(LLDPTLVFields);
-        hdrFieldCoordMap = fieldCoordinates;
+        fieldValues = new HashMap<>(LLDPTLV_FIELDS);
+        hdrFieldCoordMap = FIELD_COORDINATES;
         hdrFieldsMap = fieldValues;
     }
 
     /**
-     * Constructor that writes the passed LLDPTLV values to the hdrFieldsMap
+     * Constructor that writes the passed LLDPTLV values to the hdrFieldsMap.
      */
     public LLDPTLV(final LLDPTLV other) {
         for (Map.Entry<String, byte[]> entry : other.hdrFieldsMap.entrySet()) {
@@ -99,28 +94,30 @@ public class LLDPTLV extends Packet {
     }
 
     /**
-     * @return int - the length of TLV
+     * Returns the length of TLV.
      */
     public int getLength() {
         return (int) BitBufferHelper.toNumber(fieldValues.get(LENGTH),
-                fieldCoordinates.get(LENGTH).getRight().intValue());
+                FIELD_COORDINATES.get(LENGTH).getRight());
     }
 
     /**
-     * @return byte - the type of TLV
+     * Returns the type of TLV.
      */
     public byte getType() {
         return BitBufferHelper.getByte(fieldValues.get(TYPE));
     }
 
     /**
-     * @return byte[] - the value field of TLV
+     * Returns the value field of TLV.
      */
     public byte[] getValue() {
         return fieldValues.get(VALUE);
     }
 
     /**
+     * Sets the type.
+     *
      * @param type the type to set
      * @return LLDPTLV
      */
@@ -131,6 +128,8 @@ public class LLDPTLV extends Packet {
     }
 
     /**
+     * Sets the length.
+     *
      * @param length the length to set
      * @return LLDPTLV
      */
@@ -140,6 +139,8 @@ public class LLDPTLV extends Packet {
     }
 
     /**
+     * Sets the value.
+     *
      * @param value the value to set
      * @return LLDPTLV
      */
@@ -158,7 +159,7 @@ public class LLDPTLV extends Packet {
         final int prime = 31;
         int result = super.hashCode();
         result = prime * result
-                + ((fieldValues == null) ? 0 : fieldValues.hashCode());
+                + (fieldValues == null ? 0 : fieldValues.hashCode());
         return result;
     }
 
@@ -187,48 +188,46 @@ public class LLDPTLV extends Packet {
     @Override
     public int getfieldnumBits(final String fieldName) {
         if (fieldName.equals(VALUE)) {
-            return (NetUtils.NumBitsInAByte * BitBufferHelper.getShort(
-                    fieldValues.get(LENGTH), fieldCoordinates.get(LENGTH)
-                    .getRight().intValue()));
+            return NetUtils.NUM_BITS_IN_A_BYTE * BitBufferHelper.getShort(
+                    fieldValues.get(LENGTH), FIELD_COORDINATES.get(LENGTH).getRight());
         }
-        return fieldCoordinates.get(fieldName).getRight();
+        return FIELD_COORDINATES.get(fieldName).getRight();
     }
 
     /**
-     * Returns the size in bits of the whole TLV
+     * Returns the size in bits of the whole TLV.
      *
      * @return int - size in bits of full TLV
      */
     public int getTLVSize() {
-        return (LLDPTLV.fieldCoordinates.get(TYPE).getRight() + // static
-                LLDPTLV.fieldCoordinates.get(LENGTH).getRight() + // static
-                getfieldnumBits(VALUE)); // variable
+        return LLDPTLV.FIELD_COORDINATES.get(TYPE).getRight() + // static
+                LLDPTLV.FIELD_COORDINATES.get(LENGTH).getRight() + // static
+                getfieldnumBits(VALUE); // variable
     }
 
     /**
-     * Creates the SystemName TLV value
+     * Creates the SystemName TLV value.
      *
      * @param nodeId
      *            node identifier string
      * @return the SystemName TLV value in byte array
      */
-    static public byte[] createSystemNameTLVValue(final String nodeId) {
-        byte[] nid = nodeId.getBytes();
-        return nid;
+    public static byte[] createSystemNameTLVValue(final String nodeId) {
+        return nodeId.getBytes(StandardCharsets.UTF_8);
     }
 
     /**
-     * Creates the ChassisID TLV value including the subtype and ChassisID
-     * string
+     * Creates the ChassisID TLV value including the subtype and ChassisID string.
      *
      * @param nodeId
      *            node identifier string
      * @return the ChassisID TLV value in byte array
      */
-    static public byte[] createChassisIDTLVValue(final String nodeId) {
+    public static byte[] createChassisIDTLVValue(final String nodeId) {
         byte[] nid = HexEncode.bytesFromHexString(nodeId);
         byte[] cid = new byte[6];
-        int srcPos = 0, dstPos = 0;
+        int srcPos = 0;
+        int dstPos = 0;
 
         if (nid.length > cid.length) {
             srcPos = nid.length - cid.length;
@@ -237,65 +236,76 @@ public class LLDPTLV extends Packet {
         }
         System.arraycopy(nid, srcPos, cid, dstPos, cid.length);
 
-        byte[] cidValue = new byte[cid.length + chassisIDSubType.length];
+        byte[] cidValue = new byte[cid.length + CHASSISID_SUB_TYPE.length];
 
-        System.arraycopy(chassisIDSubType, 0, cidValue, 0,
-                chassisIDSubType.length);
-        System.arraycopy(cid, 0, cidValue, chassisIDSubType.length, cid.length);
+        System.arraycopy(CHASSISID_SUB_TYPE, 0, cidValue, 0,
+                CHASSISID_SUB_TYPE.length);
+        System.arraycopy(cid, 0, cidValue, CHASSISID_SUB_TYPE.length, cid.length);
 
         return cidValue;
     }
 
     /**
-     * Creates the PortID TLV value including the subtype and PortID string
+     * Creates the PortID TLV value including the subtype and PortID string.
      *
      * @param portId
      *            port identifier string
      * @return the PortID TLV value in byte array
      */
-    static public byte[] createPortIDTLVValue(final String portId) {
+    public static byte[] createPortIDTLVValue(final String portId) {
         byte[] pid = portId.getBytes(Charset.defaultCharset());
-        byte[] pidValue = new byte[pid.length + portIDSubType.length];
+        byte[] pidValue = new byte[pid.length + PORTID_SUB_TYPE.length];
 
-        System.arraycopy(portIDSubType, 0, pidValue, 0, portIDSubType.length);
-        System.arraycopy(pid, 0, pidValue, portIDSubType.length, pid.length);
+        System.arraycopy(PORTID_SUB_TYPE, 0, pidValue, 0, PORTID_SUB_TYPE.length);
+        System.arraycopy(pid, 0, pidValue, PORTID_SUB_TYPE.length, pid.length);
 
         return pidValue;
     }
 
     /**
-     * Creates the custom TLV value including OUI, subtype and custom string
+     * Creates the custom TLV value including OUI, subtype and custom string.
      *
      * @param customString
      *            port identifier string
      * @return the custom TLV value in byte array
      * @see #createCustomTLVValue(byte[],byte[])
      */
-    static public byte[] createCustomTLVValue(final String customString) {
+    public static byte[] createCustomTLVValue(final String customString) {
         byte[] customByteArray = customString.getBytes(Charset.defaultCharset());
         return createCustomTLVValue(CUSTOM_TLV_SUB_TYPE_NODE_CONNECTOR_ID, customByteArray);
     }
 
     /**
-     * Creates the custom TLV value including OUI, subtype and custom string
+     * Creates the custom TLV value including OUI, subtype and custom string.
+     *
      * @param subtype openflow subtype
      * @param customByteArray
      *            port identifier string
      * @return the custom TLV value in byte array
      */
-    static public byte[] createCustomTLVValue(final byte[] subtype, final byte[] customByteArray) {
-        byte[] customValue = new byte[customTlvOffset + customByteArray.length];
+    public static byte[] createCustomTLVValue(final byte[] subtype, final byte[] customByteArray) {
+        byte[] customValue = new byte[CUSTOM_TLV_OFFSET + customByteArray.length];
 
         System.arraycopy(OFOUI, 0, customValue, 0, OFOUI.length);
         System.arraycopy(subtype, 0, customValue, OFOUI.length, 1);
-        System.arraycopy(customByteArray, 0, customValue, customTlvOffset,
+        System.arraycopy(customByteArray, 0, customValue, CUSTOM_TLV_OFFSET,
                 customByteArray.length);
 
         return customValue;
     }
 
     /**
-     * Retrieves the string from TLV value and returns it in HexString format
+     * Creates a custom TLV value including OUI of sub type custom sec and custom bytes value.
+     *
+     * @param customValue the custom value
+     * @return the custom TLV value in byte array
+     */
+    public static byte[] createSecSubTypeCustomTLVValue(final byte[] customValue) {
+        return createCustomTLVValue(CUSTOM_TLV_SUB_TYPE_CUSTOM_SEC, customValue);
+    }
+
+    /**
+     * Retrieves the string from TLV value and returns it in HexString format.
      *
      * @param tlvValue
      *            the TLV value
@@ -303,15 +313,15 @@ public class LLDPTLV extends Packet {
      *            the TLV length
      * @return the HexString
      */
-    static public String getHexStringValue(final byte[] tlvValue, final int tlvLen) {
-        byte[] cidBytes = new byte[tlvLen - chassisIDSubType.length];
-        System.arraycopy(tlvValue, chassisIDSubType.length, cidBytes, 0,
+    public static String getHexStringValue(final byte[] tlvValue, final int tlvLen) {
+        byte[] cidBytes = new byte[tlvLen - CHASSISID_SUB_TYPE.length];
+        System.arraycopy(tlvValue, CHASSISID_SUB_TYPE.length, cidBytes, 0,
                 cidBytes.length);
         return HexEncode.bytesToHexStringFormat(cidBytes);
     }
 
     /**
-     * Retrieves the string from TLV value
+     * Retrieves the string from TLV value.
      *
      * @param tlvValue
      *            the TLV value
@@ -319,23 +329,22 @@ public class LLDPTLV extends Packet {
      *            the TLV length
      * @return the string
      */
-    static public String getStringValue(final byte[] tlvValue, final int tlvLen) {
-        byte[] pidSubType = new byte[portIDSubType.length];
-        byte[] pidBytes = new byte[tlvLen - portIDSubType.length];
+    public static String getStringValue(final byte[] tlvValue, final int tlvLen) {
+        byte[] pidSubType = new byte[PORTID_SUB_TYPE.length];
+        byte[] pidBytes = new byte[tlvLen - PORTID_SUB_TYPE.length];
         System.arraycopy(tlvValue, 0, pidSubType, 0,
                 pidSubType.length);
-        System.arraycopy(tlvValue, portIDSubType.length, pidBytes, 0,
+        System.arraycopy(tlvValue, PORTID_SUB_TYPE.length, pidBytes, 0,
                 pidBytes.length);
         if (pidSubType[0] == (byte) 0x3) {
             return HexEncode.bytesToHexStringFormat(pidBytes);
         } else {
-            return (new String(pidBytes, Charset.defaultCharset()));
+            return new String(pidBytes, Charset.defaultCharset());
         }
     }
 
     /**
-     * Retrieves the custom string from the Custom TLV value which includes OUI,
-     * subtype and custom string
+     * Retrieves the custom string from the Custom TLV value which includes OUI, subtype and custom string.
      *
      * @param customTlvValue
      *            the custom TLV value
@@ -343,18 +352,18 @@ public class LLDPTLV extends Packet {
      *            the custom TLV length
      * @return the custom string
      */
-    static public String getCustomString(final byte[] customTlvValue, final int customTlvLen) {
+    public static String getCustomString(final byte[] customTlvValue, final int customTlvLen) {
         String customString = "";
         byte[] vendor = new byte[3];
         System.arraycopy(customTlvValue, 0, vendor, 0, vendor.length);
         if (Arrays.equals(vendor, LLDPTLV.OFOUI)) {
-            int customArrayLength = customTlvLen - customTlvOffset;
+            int customArrayLength = customTlvLen - CUSTOM_TLV_OFFSET;
             byte[] customArray = new byte[customArrayLength];
-            System.arraycopy(customTlvValue, customTlvOffset, customArray, 0,
-                    customArrayLength);
+            System.arraycopy(customTlvValue, CUSTOM_TLV_OFFSET, customArray, 0, customArrayLength);
             try {
                 customString = new String(customArray, "UTF-8");
             } catch (final UnsupportedEncodingException e) {
+                LOG.warn("Error creating string from the custom TLV value: {}", Arrays.toString(customTlvValue), e);
             }
         }
 
@@ -370,4 +379,13 @@ public class LLDPTLV extends Packet {
         byte[] value = lldptlv.getValue();
         return BitBufferHelper.getByte(ArrayUtils.subarray(value, 3, 4));
     }
+
+    public static CustomTLVKey createPortSubTypeCustomTLVKey() {
+        return new CustomTLVKey(BitBufferHelper.getInt(OFOUI), CUSTOM_TLV_SUB_TYPE_NODE_CONNECTOR_ID[0]);
+    }
+
+    public static CustomTLVKey createSecSubTypeCustomTLVKey() {
+        return new CustomTLVKey(BitBufferHelper.getInt(LLDPTLV.OFOUI), LLDPTLV.CUSTOM_TLV_SUB_TYPE_CUSTOM_SEC[0]);
+    }
 }
+