ONOS-4083, ONOS-4084, ONOS-4096, ONOS-4097:ISIS PDU Data Structures

Change-Id: I22d30e8f7ba7d414e75254fdec6d0865bf471ff9
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
new file mode 100644
index 0000000..1dfb1a4
--- /dev/null
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2016-present 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.isis.io.util;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisNeighbor;
+import org.onosproject.isis.controller.IsisNetworkType;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.io.isispacket.IsisHeader;
+import org.onosproject.isis.io.isispacket.pdu.AttachedToOtherAreas;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.isispacket.tlv.AreaAddressTlv;
+import org.onosproject.isis.io.isispacket.tlv.HostNameTlv;
+import org.onosproject.isis.io.isispacket.tlv.IpInterfaceAddressTlv;
+import org.onosproject.isis.io.isispacket.tlv.IpInternalReachabilityTlv;
+import org.onosproject.isis.io.isispacket.tlv.IsReachabilityTlv;
+import org.onosproject.isis.io.isispacket.tlv.MetricOfInternalReachability;
+import org.onosproject.isis.io.isispacket.tlv.MetricsOfReachability;
+import org.onosproject.isis.io.isispacket.tlv.ProtocolSupportedTlv;
+import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
+import org.onosproject.isis.io.isispacket.tlv.TlvType;
+
+import java.util.List;
+
+/**
+ * Representation of link state PDU generator.
+ */
+public class LspGenerator {
+
+    public LsPdu getLsp(IsisInterface isisInterface, String lspId, IsisPduType isisPduType,
+                        List<Ip4Address> allConfiguredInterfaceIps) {
+        IsisHeader header = getHeader(isisPduType);
+        LsPdu lsp = new LsPdu(header);
+
+        lsp.setPduLength(0);
+        lsp.setRemainingLifeTime(IsisConstants.LSPMAXAGE);
+        lsp.setLspId(lspId);
+        lsp.setSequenceNumber(isisInterface.isisLsdb().lsSequenceNumber(isisPduType));
+        lsp.setCheckSum(0);
+        if (isisPduType == IsisPduType.L1LSPDU) {
+            lsp.setTypeBlock((byte) 1);
+            lsp.setIntermediateSystemType((byte) 1);
+        } else if (isisPduType == IsisPduType.L2LSPDU) {
+            lsp.setTypeBlock((byte) 3);
+            lsp.setIntermediateSystemType((byte) 3);
+        }
+        lsp.setAttachedToOtherAreas(AttachedToOtherAreas.NONE);
+        lsp.setPartitionRepair(false);
+        lsp.setLspDbol(false);
+
+        TlvHeader tlvHeader = new TlvHeader();
+        tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
+        areaAddressTlv.addAddress(isisInterface.areaAddress());
+        lsp.addTlv(areaAddressTlv);
+
+        tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
+        tlvHeader.setTlvLength(0);
+        ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
+        protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
+        lsp.addTlv(protocolSupportedTlv);
+
+        tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
+        for (Ip4Address ipaddress : allConfiguredInterfaceIps) {
+            ipInterfaceAddressTlv.addInterfaceAddres(ipaddress);
+        }
+        lsp.addTlv(ipInterfaceAddressTlv);
+
+        tlvHeader.setTlvType(TlvType.HOSTNAME.value());
+        tlvHeader.setTlvLength(0);
+        HostNameTlv hostNameTlv = new HostNameTlv(tlvHeader);
+        hostNameTlv.setHostName(isisInterface.intermediateSystemName());
+        lsp.addTlv(hostNameTlv);
+
+        tlvHeader.setTlvType(TlvType.ISREACHABILITY.value());
+        tlvHeader.setTlvLength(0);
+        IsReachabilityTlv isReachabilityTlv = new IsReachabilityTlv(tlvHeader);
+        isReachabilityTlv.setReserved(0);
+        MetricsOfReachability metricsOfReachability = new MetricsOfReachability();
+        metricsOfReachability.setDefaultMetric((byte) 10);
+        metricsOfReachability.setDefaultIsInternal(true);
+        metricsOfReachability.setDelayMetric((byte) 10);
+        metricsOfReachability.setDelayIsInternal(true);
+        metricsOfReachability.setDelayMetricSupported(true);
+        metricsOfReachability.setExpenseMetric((byte) 10);
+        metricsOfReachability.setExpenseIsInternal(true);
+        metricsOfReachability.setExpenseMetricSupported(true);
+        metricsOfReachability.setErrorMetric((byte) 10);
+        metricsOfReachability.setErrorIsInternal(true);
+        metricsOfReachability.setErrorMetricSupported(true);
+        if (isisInterface.networkType() == IsisNetworkType.BROADCAST) {
+            if (isisPduType == IsisPduType.L1LSPDU) {
+                metricsOfReachability.setNeighborId(isisInterface.l1LanId());
+            } else if (isisPduType == IsisPduType.L2LSPDU) {
+                metricsOfReachability.setNeighborId(isisInterface.l2LanId());
+            }
+        } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
+            MacAddress neighborMac = isisInterface.neighbors().iterator().next();
+            IsisNeighbor neighbor = isisInterface.lookup(neighborMac);
+            metricsOfReachability.setNeighborId(neighbor.neighborSystemId());
+        }
+
+        isReachabilityTlv.addMeticsOfReachability(metricsOfReachability);
+        lsp.addTlv(isReachabilityTlv);
+
+        tlvHeader.setTlvType(TlvType.IPINTERNALREACHABILITY.value());
+        tlvHeader.setTlvLength(0);
+        IpInternalReachabilityTlv ipInterReacTlv = new IpInternalReachabilityTlv(tlvHeader);
+        MetricOfInternalReachability metricOfIntRea = new MetricOfInternalReachability();
+        metricOfIntRea.setDefaultMetric((byte) 10);
+        metricOfIntRea.setDefaultIsInternal(true);
+        metricOfIntRea.setDefaultDistributionDown(true);
+        metricOfIntRea.setDelayMetric((byte) 0);
+        metricOfIntRea.setDelayMetricSupported(false);
+        metricOfIntRea.setDelayIsInternal(true);
+        metricOfIntRea.setExpenseMetric((byte) 0);
+        metricOfIntRea.setExpenseMetricSupported(false);
+        metricOfIntRea.setExpenseIsInternal(true);
+        metricOfIntRea.setErrorMetric((byte) 0);
+        metricOfIntRea.setErrorMetricSupported(false);
+        metricOfIntRea.setExpenseIsInternal(true);
+        metricOfIntRea.setIpAddress(isisInterface.interfaceIpAddress());
+        metricOfIntRea.setSubnetAddres(Ip4Address.valueOf(isisInterface.networkMask()));
+        ipInterReacTlv.addInternalReachabilityMetric(metricOfIntRea);
+        lsp.addTlv(ipInterReacTlv);
+        return lsp;
+    }
+
+    public IsisHeader getHeader(IsisPduType pduType) {
+        IsisHeader isisHeader = new IsisHeader();
+        isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
+        isisHeader.setPduHeaderLength((byte) IsisUtil.getPduHeaderLength(pduType.value()));
+        isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
+        isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+        isisHeader.setIsisPduType(pduType.value());
+        isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
+        isisHeader.setReserved((byte) IsisConstants.RESERVED);
+        isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
+        return isisHeader;
+    }
+}
\ No newline at end of file