[onos-2603] - Implement LinkState attributes

Change-Id: I78192ba9e0ec930417ef4a0e71531dcfd9c6d3e5
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
new file mode 100755
index 0000000..f64abd0
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
@@ -0,0 +1,308 @@
+/*
+ * 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;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeName;
+import org.onosproject.bgpio.types.attr.BgpAttrOpaqueNode;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV6;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIsIsAdminstGrp;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMplsProtocolMask;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrName;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrOpaqLnkAttrib;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrSrlg;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrUnRsrvdLinkBandwidth;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrExtRouteTag;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrIgpFlags;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrMetric;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrOspfFwdAddr;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrOpaqueData;
+import org.onosproject.bgpio.types.attr.BgpPrefixAttrRouteTag;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implements BGP Link state attribute.
+ */
+public class LinkStateAttributes implements BGPValueType {
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(LinkStateAttributes.class);
+
+    /* Node Attributes */
+    public static final short ATTR_NODE_MT_TOPOLOGY_ID = 263;
+    public static final short ATTR_NODE_FLAG_BITS = 1024;
+    public static final short ATTR_NODE_OPAQUE_NODE = 1025;
+    public static final short ATTR_NODE_NAME = 1026;
+    public static final short ATTR_NODE_ISIS_AREA_ID = 1027;
+    public static final short ATTR_NODE_IPV4_LOCAL_ROUTER_ID = 1028;
+    public static final short ATTR_NODE_IPV6_LOCAL_ROUTER_ID = 1029;
+
+    /* Link Attributes */
+    public static final short ATTR_LINK_IPV4_REMOTE_ROUTER_ID = 1030;
+    public static final short ATTR_LINK_IPV6_REMOTE_ROUTER_ID = 1031;
+    public static final short ATTR_LINK_ADMINISTRATIVE_GRPS = 1088;
+    public static final short ATTR_LINK_MAX_BANDWIDTH = 1089;
+    public static final short ATTR_LINK_MAX_RES_BANDWIDTH = 1090;
+    public static final short ATTR_LINK_UNRES_BANDWIDTH = 1091;
+    public static final short ATTR_LINK_TE_DEFAULT_METRIC = 1092;
+    public static final short ATTR_LINK_PROTECTION_TYPE = 1093;
+    public static final short ATTR_LINK_MPLS_PROTOCOL_MASK = 1094;
+    public static final short ATTR_LINK_IGP_METRIC = 1095;
+    public static final short ATTR_LINK_SHR_RISK_GRP = 1096;
+    public static final short ATTR_LINK_OPAQUE_ATTR = 1097;
+    public static final short ATTR_LINK_NAME_ATTR = 1098;
+
+    /* Prefix Attributes */
+    public static final short ATTR_PREFIX_IGP_FLAG = 1152;
+    public static final short ATTR_PREFIX_ROUTE_TAG = 1153;
+    public static final short ATTR_PREFIX_EXTENDED_TAG = 1154;
+    public static final short ATTR_PREFIX_METRIC = 1155;
+    public static final short ATTR_PREFIX_OSPF_FWD_ADDR = 1156;
+    public static final short ATTR_PREFIX_OPAQUE_ATTR = 1157;
+
+    public static final byte LINKSTATE_ATTRIB_TYPE = 50;
+    public static final byte TYPE_AND_LEN = 4;
+    private boolean isLinkStateAttribute = false;
+    private List<BGPValueType> linkStateAttribList;
+
+    /**
+     * Constructor to reset parameters.
+     */
+    LinkStateAttributes() {
+        this.linkStateAttribList = null;
+    }
+
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param linkStateAttribList Linked list of Link, Node and Prefix TLVs
+     */
+    LinkStateAttributes(List<BGPValueType> linkStateAttribList) {
+        this.linkStateAttribList = linkStateAttribList;
+        this.isLinkStateAttribute = true;
+    }
+
+    /**
+     * Returns linked list of Link, Node and Prefix TLVs.
+     *
+     * @return linked list of Link, Node and Prefix TLVs
+     */
+    public List<BGPValueType> linkStateAttributes() {
+        return this.linkStateAttribList;
+    }
+
+    /**
+     * Returns if the Link state attributes are set or not.
+     *
+     * @return a boolean value to to check if the LS attributes are set or not
+     */
+    public boolean isLinkStateAttributeSet() {
+        return this.isLinkStateAttribute;
+    }
+
+    /**
+     * Reads the Link state attribute TLVs.
+     *
+     * @param cb ChannelBuffer
+     * @return constructor of LinkStateAttributes
+     * @throws BGPParseException while parsing link state attributes
+     */
+    public static LinkStateAttributes read(ChannelBuffer cb)
+            throws BGPParseException {
+
+        ChannelBuffer tempBuf = cb;
+        Validation parseFlags = Validation.parseAttributeHeader(cb);
+        int len = parseFlags.isShort() ? parseFlags.getLength() + TYPE_AND_LEN
+                                      : parseFlags.getLength() + 3;
+
+        ChannelBuffer data = tempBuf.readBytes(len);
+        if (!parseFlags.getFirstBit() || parseFlags.getSecondBit()
+                || parseFlags.getThirdBit()) {
+            throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                                        BGPErrorType.ATTRIBUTE_FLAGS_ERROR,
+                                        data);
+        }
+
+        if (cb.readableBytes() < parseFlags.getLength()) {
+            Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                                   BGPErrorType.BAD_MESSAGE_LENGTH,
+                                   parseFlags.getLength());
+        }
+
+        BGPValueType bgpLSAttrib = null;
+        LinkedList<BGPValueType> linkStateAttribList;
+        linkStateAttribList = new LinkedList<BGPValueType>();
+        ChannelBuffer tempCb = cb.readBytes(parseFlags.getLength());
+        while (tempCb.readableBytes() > 0) {
+            short tlvCodePoint = tempCb.readShort();
+            switch (tlvCodePoint) {
+
+            /********* 7 NODE ATTRIBUTES ********/
+            case ATTR_NODE_MT_TOPOLOGY_ID: /* 263 Multi-Topology Identifier*/
+                bgpLSAttrib = BgpAttrNodeMultiTopologyId.read(tempCb);
+                break;
+
+            case ATTR_NODE_FLAG_BITS: /*Node flag bit TLV*/
+                bgpLSAttrib = BgpAttrNodeFlagBitTlv.read(tempCb);
+                break;
+
+            case ATTR_NODE_OPAQUE_NODE: /*Opaque Node Attribute*/
+                bgpLSAttrib = BgpAttrOpaqueNode.read(tempCb);
+                break;
+
+            case ATTR_NODE_NAME: /*Node Name*/
+                bgpLSAttrib = BgpAttrNodeName.read(tempCb);
+                break;
+
+            case ATTR_NODE_ISIS_AREA_ID: /*IS-IS Area Identifier TLV*/
+                bgpLSAttrib = BgpAttrNodeIsIsAreaId.read(tempCb);
+                break;
+
+            case ATTR_NODE_IPV4_LOCAL_ROUTER_ID: /*IPv4 Router-ID of Local Node*/
+                bgpLSAttrib = BgpAttrRouterIdV4.read(tempCb, (short) ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+                break;
+
+            case ATTR_NODE_IPV6_LOCAL_ROUTER_ID: /*IPv6 Router-ID of Local Node*/
+                bgpLSAttrib = BgpAttrRouterIdV6.read(tempCb, (short) ATTR_NODE_IPV6_LOCAL_ROUTER_ID);
+                break;
+
+            /********* 15 LINK ATTRIBUTES ********/
+
+            case ATTR_LINK_IPV4_REMOTE_ROUTER_ID: /*IPv4 Router-ID of Remote Node*/
+                bgpLSAttrib = BgpAttrRouterIdV4.read(tempCb, (short) 1030);
+                break;
+
+            case ATTR_LINK_IPV6_REMOTE_ROUTER_ID: /*IPv6 Router-ID of Remote Node*/
+                bgpLSAttrib = BgpAttrRouterIdV6.read(tempCb, (short) 1031);
+                break;
+
+            case ATTR_LINK_ADMINISTRATIVE_GRPS: /*ISIS Administrative group STLV 3*/
+                bgpLSAttrib = BgpLinkAttrIsIsAdminstGrp.read(tempCb);
+                break;
+
+            case ATTR_LINK_MAX_BANDWIDTH: /*Maximum link bandwidth*/
+                bgpLSAttrib = BgpLinkAttrMaxLinkBandwidth.read(tempCb,
+                                                               (short) 1089);
+                break;
+
+            case ATTR_LINK_MAX_RES_BANDWIDTH: /* Maximum Reservable link bandwidth */
+                bgpLSAttrib = BgpLinkAttrMaxLinkBandwidth.read(tempCb,
+                                                               (short) 1090);
+                break;
+
+            case ATTR_LINK_UNRES_BANDWIDTH: /* UnReserved link bandwidth */
+                bgpLSAttrib = BgpLinkAttrUnRsrvdLinkBandwidth
+                        .read(tempCb, (short) 1091);
+                break;
+
+            case ATTR_LINK_TE_DEFAULT_METRIC: /* TE Default Metric */
+                bgpLSAttrib = BgpLinkAttrTeDefaultMetric.read(tempCb);
+                break;
+
+            case ATTR_LINK_PROTECTION_TYPE:/* Link Protection type */
+                bgpLSAttrib = BgpLinkAttrProtectionType.read(tempCb);
+                break;
+
+            case ATTR_LINK_MPLS_PROTOCOL_MASK: /* MPLS Protocol Mask */
+                bgpLSAttrib = BgpLinkAttrMplsProtocolMask.read(tempCb); // 2
+                break;
+
+            case ATTR_LINK_IGP_METRIC: /* IGP Metric */
+                bgpLSAttrib = BgpLinkAttrIgpMetric.read(tempCb); // 2
+                break;
+
+            case ATTR_LINK_SHR_RISK_GRP: /* Shared Risk Link Group */
+                bgpLSAttrib = BgpLinkAttrSrlg.read(tempCb); // 3
+                break;
+
+            case ATTR_LINK_OPAQUE_ATTR: /* Opaque link attribute */
+                bgpLSAttrib = BgpLinkAttrOpaqLnkAttrib.read(tempCb);
+                break;
+
+            case ATTR_LINK_NAME_ATTR: /* Link Name attribute */
+                bgpLSAttrib = BgpLinkAttrName.read(tempCb);
+                break;
+
+            /********* 6 PREFIX ATTRIBUTES ********/
+
+            case ATTR_PREFIX_IGP_FLAG: /* IGP Flags */
+                bgpLSAttrib = BgpPrefixAttrIgpFlags.read(tempCb);
+                break;
+
+            case ATTR_PREFIX_ROUTE_TAG: /* Route Tag */
+                bgpLSAttrib = BgpPrefixAttrRouteTag.read(tempCb);
+                break;
+
+            case ATTR_PREFIX_EXTENDED_TAG: /* Extended Tag */
+                bgpLSAttrib = BgpPrefixAttrExtRouteTag.read(tempCb);
+                break;
+
+            case ATTR_PREFIX_METRIC: /* Prefix Metric */
+                bgpLSAttrib = BgpPrefixAttrMetric.read(tempCb);
+                break;
+
+            case ATTR_PREFIX_OSPF_FWD_ADDR: /* OSPF Forwarding Address */
+                bgpLSAttrib = BgpPrefixAttrOspfFwdAddr.read(tempCb);
+                break;
+
+            case ATTR_PREFIX_OPAQUE_ATTR: /* Opaque Prefix Attribute */
+                bgpLSAttrib = BgpPrefixAttrOpaqueData.read(tempCb);
+                break;
+
+            default:
+                throw new BGPParseException(
+                                            "The BGP-LS Attribute is not supported : "
+                                                    + tlvCodePoint);
+            }
+
+            linkStateAttribList.add(bgpLSAttrib);
+        }
+        return new LinkStateAttributes(linkStateAttribList);
+    }
+
+    @Override
+    public short getType() {
+        return LINKSTATE_ATTRIB_TYPE;
+    }
+
+    @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()).omitNullValues()
+                .add("linkStateAttribList", linkStateAttribList).toString();
+    }
+}