[Emu][onos-2603] - Implement LinkState Link attributes-Link IGP Metric

Change-Id: I700922df22f5379679b3a5859cc3533f5532ae5a
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java
new file mode 100755
index 0000000..c1cb299
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.types.attr;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.types.BGPErrorType;
+import org.onosproject.bgpio.types.BGPValueType;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implements BGP link IGP metric attribute.
+ */
+public class BgpLinkAttrIgpMetric implements BGPValueType {
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(BgpLinkAttrIgpMetric.class);
+
+    public static final int ATTRLINK_IGPMETRIC = 1095;
+    public static final int ATTRLINK_MAX_LEN = 3;
+
+    /* Variable metric length based on protocol */
+    public static final int ISIS_SMALL_METRIC = 1;
+    public static final int OSPF_LINK_METRIC = 2;
+    public static final int ISIS_WIDE_METRIC = 3;
+
+    /* IGP Metric */
+    private final int igpMetric;
+    private final int igpMetricLen;
+
+    /**
+     * Constructor to initialize the value.
+     *
+     * @param igpMetric 3 byte IGP metric data.
+     * @param igpMetricLen length of IGP metric data.
+     */
+    public BgpLinkAttrIgpMetric(final int igpMetric, final int igpMetricLen) {
+        this.igpMetric = igpMetric;
+        this.igpMetricLen = igpMetricLen;
+    }
+
+    /**
+     * Returns object of this class with specified values.
+     *
+     * @param igpMetric 3 byte IGP metric data.
+     * @param igpMetricLen length of IGP metric data.
+     * @return object of BgpLinkAttrIgpMetric
+     */
+    public static BgpLinkAttrIgpMetric of(final int igpMetric,
+                                          final int igpMetricLen) {
+        return new BgpLinkAttrIgpMetric(igpMetric, igpMetricLen);
+    }
+
+    /**
+     * Reads the BGP link attributes IGP Metric.
+     *
+     * @param cb Channel buffer
+     * @return object of type BgpLinkAttrIgpMetric
+     * @throws BGPParseException while parsing BgpLinkAttrIgpMetric
+     */
+    public static BgpLinkAttrIgpMetric read(ChannelBuffer cb)
+            throws BGPParseException {
+
+        short linkigp;
+        int igpMetric = 0;
+        int igpMetricLen = 0;
+
+        short lsAttrLength = cb.readShort();
+
+        if (cb.readableBytes() < lsAttrLength
+                || lsAttrLength > ATTRLINK_MAX_LEN) {
+            Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                                   BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+                                   lsAttrLength);
+        }
+
+        switch (lsAttrLength) {
+        case ISIS_SMALL_METRIC:
+            igpMetric = cb.readByte();
+            igpMetricLen = ISIS_SMALL_METRIC;
+            break;
+        case OSPF_LINK_METRIC:
+            igpMetric = cb.readShort();
+            igpMetricLen = OSPF_LINK_METRIC;
+            break;
+        case ISIS_WIDE_METRIC:
+            linkigp = cb.readShort();
+            igpMetric = cb.readByte();
+            igpMetric = (igpMetric << 16) | linkigp;
+            igpMetricLen = ISIS_WIDE_METRIC;
+            break;
+        default: // validation is already in place
+            break;
+        }
+
+        return BgpLinkAttrIgpMetric.of(igpMetric, igpMetricLen);
+    }
+
+    /**
+     * Returns the variable length IGP metric data.
+     *
+     * @return IGP metric data
+     */
+    public int attrLinkIgpMetric() {
+        return igpMetric;
+    }
+
+    /**
+     * Returns IGP metric data length.
+     *
+     * @return IGP metric length
+     */
+    public int attrLinkIgpMetricLength() {
+        return igpMetricLen;
+    }
+
+    @Override
+    public short getType() {
+        return ATTRLINK_IGPMETRIC;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(igpMetric, igpMetricLen);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof BgpLinkAttrIgpMetric) {
+            BgpLinkAttrIgpMetric other = (BgpLinkAttrIgpMetric) obj;
+            return Objects.equals(igpMetric, other.igpMetric)
+                    && Objects.equals(igpMetricLen, other.igpMetricLen);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        // TODO This will be implemented in the next version
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("igpMetric", igpMetric).add("igpMetricLen", igpMetricLen)
+                .toString();
+    }
+}