diff --git a/app/app.xml b/app/app.xml
new file mode 100644
index 0000000..5356a65
--- /dev/null
+++ b/app/app.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Foundation
+  ~
+  ~ 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.
+  -->
+<app name="org.opencord.olttopology" origin="ON.Lab" version="${project.version}"
+     category="Topology" url="http://onosproject.org" title="Optical Line Terminal Topology App"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}" apps="org.opencord.sadis">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/olttopology-api/${project.version}</artifact>
+</app>
diff --git a/app/features.xml b/app/features.xml
new file mode 100644
index 0000000..592e5ef
--- /dev/null
+++ b/app/features.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2016-present Open Networking Foundation
+  ~
+  ~ 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/olttopology-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/app/pom.xml b/app/pom.xml
new file mode 100644
index 0000000..4ae3c3d
--- /dev/null
+++ b/app/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Foundation
+  ~
+  ~ 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.
+  -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencord</groupId>
+        <artifactId>olttopology</artifactId>
+        <version>1.0.1</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>olttopology-app</artifactId>
+
+    <packaging>bundle</packaging>
+    <description>OLT application for CORD</description>
+
+    <properties>
+        <web.context>/onos/olttopology</web.context>
+        <api.version>1.0.0</api.version>
+        <api.title>ONOS OLT TOPOLOGY REST API</api.title>
+        <api.description>
+            APIs for interacting with the CORD OLT application.
+        </api.description>
+        <api.package>org.opencord.olttopology.rest</api.package>
+        <olttopology.api.version>1.0.1</olttopology.api.version>
+        <sadis.api.version>5.0.0</sadis.api.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>olttopology-api</artifactId>
+            <version>${olttopology.api.version}</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>sadis-api</artifactId>
+            <version>${sadis.api.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${onos.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Include-Resource>
+                            WEB-INF/classes/apidoc/swagger.json=target/swagger.json
+                        </Include-Resource>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            *,org.glassfish.jersey.servlet
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                        <Karaf-Commands>org.opencord.olttopology.cli</Karaf-Commands>
+                    </instructions>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/app/src/main/java/org/opencord/olttopology/cli/OltTopologyGetCommand.java b/app/src/main/java/org/opencord/olttopology/cli/OltTopologyGetCommand.java
new file mode 100644
index 0000000..7acbac8
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/cli/OltTopologyGetCommand.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.cli;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.opencord.olttopology.OltNeighborInfo;
+import org.opencord.olttopology.OltTopologyInformationService;
+
+import java.util.Map;
+
+/**
+ * OLT Topology CLI Command.
+ * <p>
+ * Shows the current topology in the CLI.
+ */
+@Service
+@Command(scope = "onos", name = "olt-topology", description = "OLT Topology CLI command")
+public class OltTopologyGetCommand extends AbstractShellCommand {
+
+    private static final String FORMAT = "%s";
+
+    private OltTopologyInformationService oltTopoSer = get(OltTopologyInformationService.class);
+
+    @Override
+    protected void doExecute() {
+        oltTopoSer.getNeighbours().entrySet().forEach(this::display);
+    }
+
+    private void display(Map.Entry<ConnectPoint, OltNeighborInfo> neighbor) {
+        print(FORMAT, neighbor.getValue());
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/opencord/olttopology/cli/package-info.java b/app/src/main/java/org/opencord/olttopology/cli/package-info.java
new file mode 100644
index 0000000..2e664a7
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * OLT application handling PMC OLT hardware.
+ */
+package org.opencord.olttopology.cli;
diff --git a/app/src/main/java/org/opencord/olttopology/impl/OltTopology.java b/app/src/main/java/org/opencord/olttopology/impl/OltTopology.java
new file mode 100644
index 0000000..a0bf497
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/OltTopology.java
@@ -0,0 +1,770 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.impl;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.LLDP;
+import org.onlab.packet.LLDPTLV;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.codec.CodecService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.opencord.olttopology.OltNeighborInfo;
+import org.opencord.olttopology.OltTopologyInformationService;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.get;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_CHASSIS_ID;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_CHASSIS_ID_DEFAULT;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS_DEFAULT;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_TTL_IN_SECS;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_TTL_IN_SECS_DEFAULT;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.DEFAULT_LLDP_SEND_PERIODICITY;
+import static org.opencord.olttopology.impl.OsgiPropertyConstants.LLDP_SEND_PERIODICITY_STR;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Application to keep track of the topology of OLT devices.
+ */
+@Component(immediate = true,
+        property = {
+                DEFAULT_DEST_MAC_ADDRESS + ":String=" + DEFAULT_DEST_MAC_ADDRESS_DEFAULT,
+                DEFAULT_TTL_IN_SECS + ":Integer=" + DEFAULT_TTL_IN_SECS_DEFAULT,
+                DEFAULT_CHASSIS_ID + ":Integer=" + DEFAULT_CHASSIS_ID_DEFAULT,
+                LLDP_SEND_PERIODICITY_STR + ":Integer=" + DEFAULT_LLDP_SEND_PERIODICITY
+        }
+)
+public class OltTopology implements OltTopologyInformationService {
+    // Subtype value for IPv4 as per the LLDP specs
+    public static final byte IP_ADDR_SUB_TYPE = 0x1;
+    // 5 below is address subtype + IP4 address len
+    public static final byte IP_ADDR_STRING_LEN = 0x5;
+    // Value of interface sub type as per the LLDP specs
+    public static final byte INTERFACE_SUB_TYPE = 0x1;
+    // Value of interface number set in the management address
+    // field of LLDP packets being sent out
+    public static final int INTERFACE_NUM = 0;
+    // Value of the OID set in the management address field of
+    // LLDP packets being sent out
+    public static final byte OID_STRING = 0x0;
+    // Value of SystemName TLV as per the LLDP specs
+    public static final byte SYSTEMNAME_TLV_TYPE = 0x5;
+    // Value of Management Address TLV as per the LLDP specs
+    public static final byte MANAGEMENT_ADDR_TLV_TYPE = 0x8;
+    // Value of Port TLV sub type as per the LLDP specs
+    public static final byte PORT_TLV_SUB_TYPE = 5;
+    private static final String APP_NAME = "org.opencord.olttopology";
+    // Name for the consistent map where the neighbor information is stored
+    private static final String NEIGHBORS = "olt-neighbors";
+    private final Logger log = getLogger(getClass());
+    // deviceListener to be able to receive events about the OLT devices
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+    // Service to execute periodic sending of LLDP packets
+    private final ScheduledExecutorService scheduledExecutorService =
+            Executors.newSingleThreadScheduledExecutor();
+    // our application-specific event handler for processing LLDP messages
+    // received from the OLT devices
+    private final ReactivePacketProcessor processor = new ReactivePacketProcessor();
+    // Map for storing information about the OLTs, is map of OLT deviceId to
+    // uplink port of the OLT
+    private final Map<DeviceId, Port> oltPortMap = new ConcurrentHashMap<>();
+    // cfg variable to set the parameters dynamically.
+    protected String destMacAddress = DEFAULT_DEST_MAC_ADDRESS_DEFAULT;
+    // References to the various services that this app uses
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected MastershipService mastershipService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected DeviceService deviceService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CoreService coreService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected ComponentConfigService componentConfigService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected PacketService packetService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected CodecService codecService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected SadisService sadisService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected FlowObjectiveService flowObjectiveService;
+    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+    private short ttlInSecs = DEFAULT_TTL_IN_SECS_DEFAULT;
+    private int chassisId = DEFAULT_CHASSIS_ID_DEFAULT;
+    private int lldpSendPeriodicity = DEFAULT_LLDP_SEND_PERIODICITY;
+    private ApplicationId appId;
+    // Map for storing information about the neighbor connected to an OLT port
+    private EventuallyConsistentMap<ConnectPoint, OltNeighborInfo> neighbors;
+    private ScheduledFuture<?> futureTask;
+
+    protected ExecutorService packetProcessorExecutor;
+    protected ExecutorService eventExecutor;
+
+    private static boolean isNniPort(Port port) {
+        if (port.annotations().keys().contains("portName")) {
+            return port.annotations().value("portName").contains("nni-");
+        }
+        return false;
+    }
+
+    @Activate
+    public void activate(ComponentContext context) {
+        modified(context);
+        appId = coreService.registerApplication(APP_NAME);
+        componentConfigService.registerProperties(getClass());
+        codecService.registerCodec(OltNeighborInfo.class, new OltTopologyInformationCodec());
+
+        subsService = sadisService.getSubscriberInfoService();
+
+        // look for all provisioned devices in Sadis and put them in oltData
+        deviceService.getDevices().forEach(this::createAndProcessDevice);
+
+        // The NEIGHBORS map should be available across ONOS instance failures,
+        // create it using the storage service.
+        KryoNamespace serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API)
+                .register(OltNeighborInfo.class)
+                .register(ConnectPoint.class)
+                .register(java.util.Date.class)
+                .register(org.onosproject.net.Port.class)
+                .register(org.onlab.packet.LLDPOrganizationalTLV.class)
+                .build();
+
+        neighbors = storageService.<ConnectPoint, OltNeighborInfo>eventuallyConsistentMapBuilder()
+                .withName(NEIGHBORS)
+                .withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+
+        deviceService.addListener(deviceListener);
+
+        // register our event handler
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+        futureTask = scheduledExecutorService.scheduleAtFixedRate(this::oltTopologyTimerTask, 0, lldpSendPeriodicity,
+                TimeUnit.MINUTES);
+        packetProcessorExecutor = newSingleThreadExecutor(groupedThreads("onos/olttopology", "packet-%d", log));
+        eventExecutor = newSingleThreadExecutor(groupedThreads("onos/olttopology", "events-%d", log));
+
+        log.info("Started with Application ID {}", appId.id());
+    }
+
+    @Deactivate
+    public void deactivate() {
+        futureTask.cancel(true);
+        scheduledExecutorService.shutdownNow();
+        packetService.removeProcessor(processor);
+        deviceService.removeListener(deviceListener);
+        codecService.unregisterCodec(OltNeighborInfo.class);
+        componentConfigService.unregisterProperties(getClass(), false);
+        packetProcessorExecutor.shutdown();
+        eventExecutor.shutdown();
+        log.info("Stopped");
+    }
+
+    @Modified
+    public void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+        try {
+            String destMac = get(properties, DEFAULT_DEST_MAC_ADDRESS);
+            destMacAddress = Objects.isNull(destMac) ? DEFAULT_DEST_MAC_ADDRESS_DEFAULT : destMac;
+            String ttlInsecsStr = get(properties, DEFAULT_TTL_IN_SECS);
+            ttlInSecs = Short.parseShort(ttlInsecsStr.trim());
+
+            String chassisIdStr = get(properties, DEFAULT_CHASSIS_ID);
+            chassisId = Integer.parseInt(chassisIdStr.trim());
+
+            String lldpPeriodicity = get(properties, LLDP_SEND_PERIODICITY_STR);
+            int newLldpSendPeriodicity = Integer.parseInt(lldpPeriodicity);
+
+            if (newLldpSendPeriodicity <= 0) {
+                log.error("lldpSendPeriodicity should be a positive integer");
+            } else if (newLldpSendPeriodicity != lldpSendPeriodicity) {
+                lldpSendPeriodicity = newLldpSendPeriodicity;
+                lldpPeriodicity(newLldpSendPeriodicity);
+            }
+
+            log.debug("OLT properties: destMacAddress: {}, ttlInSecs: {}, chassisId: {}, lldpSendPeriodicity{}",
+                    destMacAddress, ttlInSecs, chassisId, lldpSendPeriodicity);
+        } catch (Exception e) {
+            log.error("Error while modifying the properties", e);
+        }
+    }
+
+    @Override
+    public Map<ConnectPoint, OltNeighborInfo> getNeighbours() {
+        return neighbors.entrySet().stream().collect(Collectors.toMap(Entry::getKey, Entry::getValue));
+    }
+
+    /**
+     * Sets periodicity in minutes for sending out LLDP packet to OLT NNI Ports.
+     *
+     * @param timer Value in minutes.
+     */
+    @Override
+    public void lldpPeriodicity(int timer) {
+        if (timer > 0) {
+            if (futureTask != null) {
+                futureTask.cancel(true);
+            }
+
+            futureTask = scheduledExecutorService.scheduleAtFixedRate(this::oltTopologyTimerTask, 0,
+                    timer,
+                    TimeUnit.MINUTES);
+            log.info("LLDP Packet out Periodicity updated to {} minutes", timer);
+        }
+    }
+
+    /**
+     * Creates entry in the oltData map.
+     * provision LLDP flow on enabled NNI ports if device is present in Sadis config
+     *
+     * @param dev Device to look for
+     */
+    private void createAndProcessDevice(Device dev) {
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(dev.serialNumber());
+        log.debug("CreateAndProcessDevice: deviceInfo {}", deviceInfo);
+
+        if (deviceInfo != null) {
+            // TODO FIXME, this works only with one NNI
+            Optional<Port> optPort = deviceService.getPorts(dev.id())
+                    .stream().filter(OltTopology::isNniPort).findFirst();
+            if (optPort.isPresent()) {
+                Port port = optPort.get();
+                oltPortMap.put(dev.id(), port);
+                return;
+            }
+        }
+        log.warn("CreateAndProcessDevice: failed to update the oltdata for device {}", dev);
+    }
+
+    /**
+     * Updates OltData Map with new AccessDeviceData if it is already present in OltMap,
+     * Provisions LLDP flow on enabled NNI port if it is present in Sadis config
+     * Only one NNI port is supported as of now.
+     *
+     * @param dev    Device to look for
+     * @param uplink Uplink port number
+     * @return true if updated else false
+     */
+    private boolean updateOltData(Device dev, Port uplink) {
+        // check if this device is provisioned in Sadis
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(dev.serialNumber());
+        log.debug("updateAccessDevice: deviceInfo {}", deviceInfo);
+
+        if (deviceInfo != null) {
+            oltPortMap.replace(dev.id(), uplink);
+            log.debug("updateAccessDevice: Stored did {} uplink {}", dev.id(), uplink);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sends LLDP Packet to OLT NNI Port.
+     *
+     * @param devId   Access Device data for OLT
+     * @param nniPort NNI port info of OLT
+     */
+    private void sendLldpPackets(DeviceId devId, Port nniPort) {
+        if (!mastershipService.isLocalMaster(devId)) {
+            return;
+        }
+
+        // Get NNI Port name to be filled in LLDP packet port TLV.
+        String portName = (nniPort.annotations().value("portName").isEmpty()) ? "" :
+                nniPort.annotations().value("portName");
+
+        // Get System Name value from device name.
+        Device d = deviceService.getDevice(devId);
+        String[] systemName = d.id().uri().toString().split(":", 2);
+
+        MacAddress destMac = MacAddress.valueOf(destMacAddress);
+        MacAddress srcMac = createMacFromDevId(d.id());
+
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(d.serialNumber());
+
+        // Initialized deviceIP address, to be sent in Management Address TLV.
+        Ip4Address devIpAddr = Ip4Address.valueOf("0.0.0.0");
+
+        // Get OLT device IP address from deviceInfo, to be filled in management address TLV.
+        if (deviceInfo != null) {
+            devIpAddr = deviceInfo.ipAddress();
+            log.debug("sendLldpPackets: did {} nniPort {} devIP {}", d.id(), nniPort, devIpAddr);
+        } else {
+            log.warn("device {} not found in Sadis NOT sending LLDP packet", d.id());
+            return;
+        }
+
+        //Created LLDP packet.
+        Ethernet packet = createLldpPacket(destMac, srcMac, chassisId,
+                portName, ttlInSecs, systemName[1], devIpAddr
+                        .toString());
+
+        // Create the connect point to send the packet to and emit
+        ConnectPoint toSendTo = new ConnectPoint(d.id(), nniPort.number());
+
+        //Sends LLDP packet to connect point(NNI port).
+        TrafficTreatment t = DefaultTrafficTreatment.builder()
+                .setOutput(toSendTo.port()).build();
+        OutboundPacket o = new DefaultOutboundPacket(
+                toSendTo.deviceId(), t,
+                ByteBuffer.wrap(packet.serialize()));
+        if (log.isTraceEnabled()) {
+            log.trace("Sending LLDP packet {} at {}",
+                    packet, toSendTo);
+        }
+
+        packetService.emit(o);
+    }
+
+    /**
+     * Creates MAC address for LLDP packet from OLT device ID string.
+     *
+     * @param id Device ID of OLT
+     * @return Mac address
+     */
+    private MacAddress createMacFromDevId(DeviceId id) {
+        String strId = id.toString();
+        String macStr = strId.substring(7);
+        String formattedMac = macStr.replaceAll("(.{2})", "$1" + ":");
+        formattedMac = formattedMac.substring(0, formattedMac.length() - 1);
+
+        return MacAddress.valueOf(formattedMac);
+    }
+
+    /**
+     * Creates LLDP packet to be sent out of OLT.
+     *
+     * @param destMac    Destination LLDP Mac address
+     * @param srcMac     Source Mac of OLT device
+     * @param chassisId  Chassis ID TLV value
+     * @param port       NNI port information
+     * @param ttl        TTL value in sec
+     * @param systemName System name TLV value
+     * @param mgmtAddr   Management Address TLV value
+     * @return LLDP ethernet packet
+     */
+    private Ethernet createLldpPacket(MacAddress destMac, MacAddress srcMac,
+                                      int chassisId, String port, short ttl,
+                                      String systemName, String mgmtAddr) {
+
+        Ethernet ethPkt = new Ethernet();
+        ethPkt.setEtherType(Ethernet.TYPE_LLDP);
+        ethPkt.setDestinationMACAddress(destMac);
+        ethPkt.setSourceMACAddress(srcMac);
+
+        LLDP lldpPkt = new LLDP();
+
+        setChassisId(lldpPkt, chassisId);
+        setPortId(lldpPkt, port);
+        setTtl(lldpPkt, ttl);
+
+        List<LLDPTLV> optionalTlv = new ArrayList<>();
+        optionalTlv.add(createSystemNameTlv(systemName));
+        optionalTlv.add(createMgmtAddressTlv(mgmtAddr));
+
+        lldpPkt.setOptionalTLVList(optionalTlv);
+
+        ethPkt.setPayload(lldpPkt);
+        return ethPkt;
+    }
+
+    /**
+     * Sets Chassis ID TLV for LLDP packet.
+     *
+     * @param lldpPkt   LLDP packet reference
+     * @param chassisId Chassid ID tlv value
+     */
+    private void setChassisId(LLDP lldpPkt, final int chassisId) {
+        final byte chassisTlvSubtype = 1;
+
+        byte[] chassis = ArrayUtils.addAll(new byte[]{chassisTlvSubtype},
+                ByteBuffer.allocate(String.valueOf(chassisId).length())
+                        .put(String.valueOf(chassisId).getBytes()).array());
+
+        LLDPTLV chassisTlv = new LLDPTLV();
+        lldpPkt.setChassisId(chassisTlv.setLength((byte) chassis.length)
+                .setType(LLDP.CHASSIS_TLV_TYPE)
+                .setValue(chassis));
+    }
+
+    /**
+     * Sets Port ID tlv for LLDP packet.
+     *
+     * @param lldpPkt   LLDP packet reference
+     * @param ifaceName Port Name TLV value
+     */
+    private void setPortId(LLDP lldpPkt, final String ifaceName) {
+
+        byte[] port = ArrayUtils.addAll(new byte[]{PORT_TLV_SUB_TYPE},
+                ifaceName.getBytes());
+
+        LLDPTLV portTlv = new LLDPTLV();
+        lldpPkt.setPortId(portTlv.setLength((byte) port.length)
+                .setType(LLDP.PORT_TLV_TYPE)
+                .setValue(port));
+    }
+
+    /**
+     * Sets  TTL tlv for LLDP packet.
+     *
+     * @param lldpPkt    LLDP Packet reference
+     * @param timeInSecs TTL tlv value in sec
+     */
+    private void setTtl(LLDP lldpPkt, final short timeInSecs) {
+        byte[] time = ByteBuffer.allocate(2).putShort(timeInSecs).array();
+
+        LLDPTLV ttlTlv = new LLDPTLV();
+
+        lldpPkt.setTtl(ttlTlv.setType(LLDP.TTL_TLV_TYPE)
+                .setLength((short) time.length)
+                .setValue(time));
+    }
+
+    /**
+     * Creates System name TLV for LLDP packet.
+     *
+     * @param systemName System name tlv value
+     * @return systemName TLV
+     */
+    private LLDPTLV createSystemNameTlv(String systemName) {
+        byte[] bytes = systemName.getBytes();
+
+        LLDPTLV sysNameTlv = new LLDPTLV();
+
+        return sysNameTlv.setType(SYSTEMNAME_TLV_TYPE)
+                .setLength((byte) bytes.length)
+                .setValue(bytes);
+    }
+
+    /**
+     * Sets Management address TLV for LLDP packet.
+     *
+     * @param mgmtAddress Management address tlv value
+     * @return Management address TLV
+     */
+    private LLDPTLV createMgmtAddressTlv(String mgmtAddress) {
+
+        Ip4Address ipAddr = Ip4Address.valueOf(mgmtAddress);
+
+        byte[] addrStr = ArrayUtils.addAll(new byte[]{IP_ADDR_SUB_TYPE},
+                ipAddr.toOctets());
+
+        byte[] ipAddrBytes = ArrayUtils.addAll(new byte[]{IP_ADDR_STRING_LEN},
+                addrStr);
+
+        byte[] bytesInterfacetype = ArrayUtils.addAll(ipAddrBytes,
+                ByteBuffer.allocate(1).put(INTERFACE_SUB_TYPE).array());
+        byte[] bytesInterfaceNumber = ArrayUtils.addAll(bytesInterfacetype,
+                ByteBuffer.allocate(4).putInt(INTERFACE_NUM).array());
+        byte[] finalMgmtAddrBytes = ArrayUtils.addAll(bytesInterfaceNumber,
+                ByteBuffer.allocate(1).put(OID_STRING).array());
+
+        LLDPTLV mgmtAddrTlv = new LLDPTLV();
+        return mgmtAddrTlv.setType(MANAGEMENT_ADDR_TLV_TYPE)
+                .setLength((byte) finalMgmtAddrBytes.length)
+                .setValue(finalMgmtAddrBytes);
+    }
+
+    /**
+     * Processes incoming LLDP packets from NNI ports.
+     *
+     * @param pkt Inbound packet received at ONOS from OLT NNI port
+     */
+    private void handleLldpPacket(InboundPacket pkt) {
+
+        Ethernet packet = pkt.parsed();
+
+        if (packet == null) {
+            log.warn("Packet is null");
+            return;
+        }
+
+        log.debug("Got a packet {}", packet);
+
+        // Check if Ethernet type is LLDP.
+        if (packet.getEtherType() == Ethernet.TYPE_LLDP) {
+            // Get payload of Packet.
+            LLDP lldpPacket = (LLDP) packet.getPayload();
+
+            // Fetch all optional TLVs from Packet.
+            List<LLDPTLV> optionalTLVs = lldpPacket.getOptionalTLVList();
+
+            // Look for the system name and neighbor
+            // management IP address TLVs.
+            String systemName = null;
+            String neighMgmtAddr = "";
+            if (optionalTLVs != null) {
+                for (LLDPTLV tlv : optionalTLVs) {
+                    // Fetching system name TLV.
+                    if (tlv.getType() == SYSTEMNAME_TLV_TYPE) {
+                        systemName = new String(tlv.getValue());
+                    } else if (tlv.getType() == MANAGEMENT_ADDR_TLV_TYPE) {
+                        /* Fetching 4 Octets from MANAGEMENT Address TLV to get IP address. */
+                        byte[] neighMgmtIpBytes = Arrays.copyOfRange(tlv.getValue(), 2, 6);
+                        Ip4Address neighMgmtIpaddress = Ip4Address.valueOf(neighMgmtIpBytes);
+                        neighMgmtAddr = neighMgmtIpaddress.toString();
+                    }
+                }
+            }
+
+            if (systemName == null) {
+                // We expect the system name to be sent by the neighbor, in absence
+                // we don't store the information
+                return;
+            }
+
+            int portIdTlvLen = lldpPacket.getPortId().getLength();
+
+            String portName = new String(lldpPacket.getPortId().getValue())
+                    .substring(1, portIdTlvLen);
+
+            // The OLT name stored in the topology information is the device uri
+            // excluding the "of:" part
+            DeviceId devId = pkt.receivedFrom().deviceId();
+            String deviceUri = devId.uri().toString();
+            String[] oltName = deviceUri.split(":", 2);
+            Port oltNni = deviceService.getPort(pkt.receivedFrom());
+
+            String devSerial = deviceService.getDevice(devId).serialNumber();
+
+            // Creating object of OltNeighborInfo with all info required.
+            OltNeighborInfo newNeighbor = new OltNeighborInfo(systemName,
+                    portName,
+                    oltName[1],
+                    oltNni,
+                    devSerial);
+            newNeighbor.setMgmtAddress(neighMgmtAddr);
+
+            // Store all the other optional in the neighbour information
+            // this is for future use
+            for (LLDPTLV tlv : optionalTLVs) {
+                if (tlv.getType() != SYSTEMNAME_TLV_TYPE && tlv.getType() != MANAGEMENT_ADDR_TLV_TYPE) {
+                    newNeighbor.addOtherOptionalLldpTlvs(tlv);
+                }
+            }
+
+            /*
+            Checking if Neighbor information is already present.
+            If Yes, then update current information, else
+            adding new information.
+             */
+            OltNeighborInfo curNeighbor = neighbors.get(pkt.receivedFrom());
+            if (newNeighbor.equals(curNeighbor)) {
+                curNeighbor.updateTimeStamp();
+                neighbors.put(pkt.receivedFrom(), curNeighbor);
+            } else {
+                // received first time on this connect point or old was purged
+                neighbors.put(pkt.receivedFrom(), newNeighbor);
+            }
+        }
+    }
+
+    /**
+     * Removes Entry for device from Olt topology table.
+     *
+     * @param devIdToRm Device ID to be removed
+     */
+    void removeNeighborsOfDevice(DeviceId devIdToRm) {
+        for (Map.Entry<ConnectPoint, OltNeighborInfo> neighEntry : neighbors.entrySet()) {
+            if (neighEntry.getKey().deviceId().toString().contains(devIdToRm.toString())) {
+                neighbors.remove(neighEntry.getKey());
+            }
+        }
+    }
+
+    /**
+     * oltTopologyTimerTask method to send LLDP packets periodically to the neighbours.
+     */
+    public void oltTopologyTimerTask() {
+        oltPortMap.forEach((key, p) -> {
+            //Port p = deviceService.getPort(key, value);
+            if (p != null  && p.isEnabled()) {
+                sendLldpPackets(key, p);
+            }
+        });
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        /**
+         * Device Listener Event, will be called if Device is added or state is changed or Updated.
+         *
+         * @param event Device event
+         */
+        @Override
+        public void event(DeviceEvent event) {
+            eventExecutor.execute(() -> {
+                DeviceId devId = event.subject().id();
+                /* Checking DEVICE_REMOVED and DEVICE_AVAILABILITY_CHANGED events before
+                Mastership check as with these events mastership check will always give false.
+                */
+                if (event.type().equals(DeviceEvent.Type.DEVICE_REMOVED)) {
+                    removeNeighborsOfDevice(devId);
+                    return;
+                } else if (event.type().equals(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED)) {
+                    if (!deviceService.isAvailable(devId)) {
+                        removeNeighborsOfDevice(devId);
+                        return;
+                    }
+                }
+
+                if (!mastershipService.isLocalMaster(devId)) {
+                    return;
+                }
+
+                switch (event.type()) {
+                    case DEVICE_ADDED:
+                        if (!oltPortMap.containsKey(devId)) {
+                            createAndProcessDevice(deviceService.getDevice(devId));
+                        }
+                        break;
+                    case PORT_ADDED:
+                    /*
+                    If NNI port is detected, update it in the map.
+                     */
+                        /* TODO: put null check for the annotations return*/
+                        if (isNniPort(event.port())) {
+                            if (oltPortMap.containsKey(devId)) {
+                                if (!updateOltData(deviceService.getDevice(devId), event.port())) {
+                                    return;
+                                }
+                            } else {
+                                return;
+                            }
+                        }
+
+                        if (Objects.nonNull(oltPortMap.get(devId)) &&
+                                oltPortMap.get(devId).equals(event.port()) &&
+                                event.port().isEnabled()) {
+                            sendLldpPackets(devId, event.port());
+                        }
+                        break;
+                    case PORT_REMOVED:
+                        // Remove from neighbor map and LLDP flow if NNI port is removed.
+                        if (Objects.nonNull(oltPortMap.get(devId)) &&
+                                oltPortMap.get(devId).equals(event.port())) {
+                            // the uplink port has been removed; remove the connect
+                            // point from the neighbors
+                            neighbors.remove(new ConnectPoint(devId, event.port().number()));
+                        }
+                        break;
+                    case PORT_UPDATED:
+                        // if Port is enabled, provision LLDP flow and send LLDP packet to NNI Port.
+                        if (!oltPortMap.get(devId).equals(event.port())) {
+                            break;
+                        }
+                        if (event.port().isEnabled()) {
+                            sendLldpPackets(devId, event.port());
+                        } else {
+                            neighbors.remove(new ConnectPoint(devId, event.port().number()));
+                        }
+                        break;
+
+                    default:
+                        log.debug("event {} not handle for the device {}", event.type(), devId);
+                        break;
+                }
+            });
+        }
+    }
+
+    /*
+     * Class to do the processing of the LLDP packets received from the Packet Service.
+     */
+    private class ReactivePacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+            packetProcessorExecutor.execute(() -> {
+                DeviceId devId = context.inPacket().receivedFrom().deviceId();
+                if (!mastershipService.isLocalMaster(devId)) {
+                    return;
+                }
+                // Extract the original Ethernet frame from the packet information
+                InboundPacket pkt = context.inPacket();
+                Ethernet ethPkt = pkt.parsed();
+
+                if (ethPkt == null) {
+                    log.warn("ethPkt null while processing context: {}", context);
+                    return;
+                }
+
+                if (EthType.EtherType.lookup(ethPkt.getEtherType()) == EthType.EtherType.LLDP) {
+                    handleLldpPacket(context.inPacket());
+                }
+            });
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/opencord/olttopology/impl/OltTopologyInformationCodec.java b/app/src/main/java/org/opencord/olttopology/impl/OltTopologyInformationCodec.java
new file mode 100644
index 0000000..bd45bed
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/OltTopologyInformationCodec.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.impl;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.LLDPTLV;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.opencord.olttopology.OltNeighborInfo;
+
+import java.util.Date;
+import java.util.List;
+
+/*
+Codec for JSON encoding of OLT topology information.
+ */
+public class OltTopologyInformationCodec extends JsonCodec<OltNeighborInfo> {
+    /**
+     * Encoder for the information in Json format.
+     *
+     * @param en      : The topology information to be encoded
+     * @param context : The context to which the Json data needs to be added
+     * @return Json Object Node
+     */
+    @Override
+    public ObjectNode encode(OltNeighborInfo en, CodecContext context) {
+        final ObjectNode result = context.mapper().createObjectNode()
+                .put("oltName", (en.oltName() == null) ? "" : en.oltName())
+                .put("oltPort", (en.oltPort().annotations().value("portName").isEmpty()) ? "" :
+                        en.oltPort().annotations().value("portName"))
+                .put("oltSerialNo", (en.oltSerialNo() == null) ? "" : en.oltSerialNo())
+                .put("neighborName", (en.neighborName() == null) ? "" : en.neighborName())
+                .put("neighborPort", (en.neighborPort() == null) ? "" : en.neighborPort())
+                .put("neighborManagementAddress", (en.mgmtAddr() == null) ? "" : en.mgmtAddr());
+
+        if (en.getOtherOptionalTlvs() != null) {
+            ArrayNode optionalTlvNodes = result.putArray("optionalTlvs");
+
+            List<LLDPTLV> optionalTlvsList = en.getOtherOptionalTlvs();
+            for (LLDPTLV tlv : optionalTlvsList) {
+                ObjectNode optionalTlvNode = context.mapper().createObjectNode();
+                optionalTlvNode.put("type", tlv.getType());
+                optionalTlvNode.put("value", "0x" + byteArrayInHex(tlv.getValue()));
+                optionalTlvNodes.add(optionalTlvNode);
+            }
+        }
+
+        Date currentTime = new Date();
+        long lastUpdatedValue = currentTime.getTime() - en.getLastUpdated().getTime();
+        long lastUpdatedSecondsValue = lastUpdatedValue / 1000;
+        result.put("last_updated", Long.toString(lastUpdatedSecondsValue));
+        return result;
+    }
+
+    /**
+     * Utility function to convert byte array to Hex String.
+     *
+     * @param bytes : The byte arrary to be converted
+     * @return Hex string representation of the byte array
+     */
+    private String byteArrayInHex(byte[] bytes) {
+        String s = "";
+        for (byte b : bytes) {
+            s += String.format("%02x", b);
+        }
+        return s;
+    }
+}
diff --git a/app/src/main/java/org/opencord/olttopology/impl/OsgiPropertyConstants.java b/app/src/main/java/org/opencord/olttopology/impl/OsgiPropertyConstants.java
new file mode 100644
index 0000000..c05d219
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/OsgiPropertyConstants.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.impl;
+
+/**
+ * Constants for default values of configurable properties.
+ */
+public final class OsgiPropertyConstants {
+    public static final String DEFAULT_DEST_MAC_ADDRESS = "destMacAddress";
+    // Destination Mac address where LLDP packet has to be sent.
+    public static final String DEFAULT_DEST_MAC_ADDRESS_DEFAULT = "01:80:c2:00:00:00";
+    public static final String DEFAULT_TTL_IN_SECS = "ttlInSecs";
+    // Default Time To Live value to be used in the LLDP packets sent out
+    public static final int DEFAULT_TTL_IN_SECS_DEFAULT = 120;
+    public static final String DEFAULT_CHASSIS_ID = "chassisId";
+    // Default ChassisId to be used in the LLDP packets sent out
+    public static final int DEFAULT_CHASSIS_ID_DEFAULT = 0;
+    // Default periodicity (in minutes) of sending the LLDP messages through OLT NNI Ports
+    public static final int DEFAULT_LLDP_SEND_PERIODICITY = 15;
+    public static final String LLDP_SEND_PERIODICITY_STR = "lldpSendPeriodicity";
+
+    private OsgiPropertyConstants() {
+    }
+}
diff --git a/app/src/main/java/org/opencord/olttopology/impl/package-info.java b/app/src/main/java/org/opencord/olttopology/impl/package-info.java
new file mode 100644
index 0000000..7104a76
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * OLT Topology application for finding the topology of OLTs.
+ */
+package org.opencord.olttopology.impl;
diff --git a/app/src/main/java/org/opencord/olttopology/rest/OltTopologyWebResource.java b/app/src/main/java/org/opencord/olttopology/rest/OltTopologyWebResource.java
new file mode 100644
index 0000000..bbd8f79
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/rest/OltTopologyWebResource.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.rest;
+import org.onosproject.rest.AbstractWebResource;
+import org.opencord.olttopology.OltNeighborInfo;
+import org.opencord.olttopology.OltTopologyInformationService;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+/**
+ * OltTopology Information Service web resource.
+ */
+@Path("oltTopologyApp")
+public class OltTopologyWebResource extends AbstractWebResource {
+    private final OltTopologyInformationService service = get(OltTopologyInformationService.class);
+    /**
+     * Shows the information about the connectivity between the
+     * ports of the OLT and ports of the leaf switch.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Path("show")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getOltTopology() {
+        Iterable<OltNeighborInfo> neighbourInfos = service.getNeighbours().values();
+        return ok(encodeArray(OltNeighborInfo.class, "entries", neighbourInfos).toString()).build();
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/opencord/olttopology/rest/package-info.java b/app/src/main/java/org/opencord/olttopology/rest/package-info.java
new file mode 100644
index 0000000..684d60d
--- /dev/null
+++ b/app/src/main/java/org/opencord/olttopology/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * REST APIs for the OltTopology application.
+ */
+package org.opencord.olttopology.rest;
diff --git a/app/src/main/webapp/WEB-INF/web.xml b/app/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..359683e
--- /dev/null
+++ b/app/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Foundation
+  ~
+  ~ 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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>OLT TOPOLOGY REST API v1.0</display-name>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Secured</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>admin</role-name>
+            <role-name>viewer</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <security-role>
+        <role-name>admin</role-name>
+        <role-name>viewer</role-name>
+    </security-role>
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>karaf</realm-name>
+    </login-config>
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>jersey.config.server.provider.classnames</param-name>
+            <param-value>
+                org.opencord.olttopology.rest.OltTopologyWebResource
+            </param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/app/src/test/java/org/opencord/olttopology/impl/OltTopologyTest.java b/app/src/test/java/org/opencord/olttopology/impl/OltTopologyTest.java
new file mode 100644
index 0000000..27eeec7
--- /dev/null
+++ b/app/src/test/java/org/opencord/olttopology/impl/OltTopologyTest.java
@@ -0,0 +1,706 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang.ArrayUtils;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ComponentContextAdapter;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.LLDP;
+import org.onlab.packet.LLDPTLV;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.codec.CodecService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Element;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.service.TestStorageService;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.onosproject.net.intent.TestTools.assertAfter;
+import static org.opencord.olttopology.impl.OltTopology.SYSTEMNAME_TLV_TYPE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Tests OLT topology app.
+ */
+public class OltTopologyTest extends OltTopologyTestBase {
+    private static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 999);
+    private static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 111);
+    private static final String CLIENT_NAS_PORT_ID = "PON 1/1";
+    private static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
+    private static final String OLT_DEV_ID = "of:0000c6b1cd40dc93";
+    private static final MacAddress OLT_MAC_ADDRESS = MacAddress.valueOf("01:02:03:04:05:06");
+    private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
+    private static final String SCHEME_NAME = "olttopology";
+    private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
+            .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
+    private final Logger log = getLogger(getClass());
+    ComponentConfigService mockConfigService =
+            EasyMock.createMock(ComponentConfigService.class);
+    CodecService mockCodecService =
+            EasyMock.createMock(CodecService.class);
+    private OltTopology oltTopology;
+    private NetworkConfigListener configListener;
+    private DeviceListener deviceListener;
+
+    @Before
+    public void setUp() {
+        oltTopology = new OltTopology();
+        oltTopology.mastershipService = new MockMastershipService();
+        oltTopology.deviceService = new MockDeviceService();
+        oltTopology.coreService = new MockCoreService();
+        oltTopology.componentConfigService = mockConfigService;
+        oltTopology.packetService = new MockPacketService();
+        oltTopology.flowObjectiveService = new MockFlowObjectiveService();
+        oltTopology.storageService = new TestStorageService();
+        oltTopology.codecService = mockCodecService;
+        oltTopology.subsService = new MockSubService();
+        oltTopology.sadisService = new MockSadisService();
+        oltTopology.subsService.get(OLT_DEV_ID).setUplinkPort(1);
+        oltTopology.activate(new ComponentContextAdapter());
+    }
+
+    @After
+    public void tearDown() {
+        oltTopology.deactivate();
+
+    }
+
+    private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did, Port port) {
+        return new DeviceEvent(type, oltTopology.deviceService.getDevice(did), port);
+
+    }
+
+    /**
+     * Fetches the sent packet at the given index. The requested packet
+     * must be the last packet on the list.
+     *
+     * @param index index into sent packets array
+     * @return packet
+     */
+    private Ethernet fetchPacket(int index) {
+        for (int iteration = 0; iteration < 20; iteration++) {
+            if (savedPackets.size() > index) {
+                return (Ethernet) savedPackets.get(index);
+            } else {
+                try {
+                    Thread.sleep(250);
+                } catch (Exception ex) {
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Testing Port Added Scenario.
+     * Note: Need to See second packet as first will be sent when MockPort is called
+     *
+     */
+    @Test
+    public void testPortAdded() {
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        Ethernet responsePacket = fetchPacket(1);
+        assertThat(responsePacket, notNullValue());
+        checkLldpPacket(responsePacket);
+    }
+
+    /**
+     * Testing Port Delete Scenario.
+     *
+     */
+    @Test
+    public void testPortDeleted() {
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        Ethernet responsePacket = fetchPacket(1);
+        assertThat(responsePacket, notNullValue());
+        checkLldpPacket(responsePacket);
+        DeviceEvent portRem = deviceEvent(DeviceEvent.Type.PORT_REMOVED, DEVICE_ID_1, port);
+        deviceListener.event(portRem);
+    }
+
+    /**
+     * Tests LLDP packet in scenario.
+     *
+     */
+    @Test
+    public void testHandlePacket() {
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        MacAddress destMac = MacAddress.valueOf(OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS_DEFAULT);
+        MacAddress srcMac = MacAddress.valueOf("c6:b1:cd:40:dc:93");
+        String serialNumber = "switch-1";
+        final short ttlInSec = 120;
+        final short chasisId = 0;
+        String portName = "p0";
+        Ip4Address devIpAddr = Ip4Address.valueOf("192.168.1.1");
+        Ethernet packet = createLldpPacket(destMac, srcMac, chasisId, portName,
+                ttlInSec, serialNumber, devIpAddr.toString());
+
+        ConnectPoint cp = new ConnectPoint(d.id(), port.number());
+        sendInboundPacket(packet, cp);
+
+        assertAfter(ASSERTION_DELAY, ASSERTION_LENGTH, () -> {
+            validateNeighborList(oltTopology.getNeighbours());
+        });
+    }
+
+    /**
+     * Tests Packet out timer functionality.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testOltTopologyTimerTask() throws Exception {
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        oltTopology.lldpPeriodicity(2);
+        Thread.sleep(2000);
+        Ethernet responsePacket = fetchPacket(1);
+        assertThat(responsePacket, notNullValue());
+        checkLldpPacket(responsePacket);
+    }
+
+    /**
+     * Testing Device Delete Scenario with Packet Out.
+     *
+     */
+    @Test
+    public void testDeviceDeleted() {
+        log.info("oltTopology {}", oltTopology);
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        Ethernet responsePacket = fetchPacket(1);
+        assertThat(responsePacket, notNullValue());
+        checkLldpPacket(responsePacket);
+        DeviceEvent portRem = deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DEVICE_ID_1, port);
+        deviceListener.event(portRem);
+    }
+
+    /**
+     * Testing Port Delete Scenario After Packet Handle for Packet in.
+     *
+     */
+    @Test
+    public void testPortDelAfterHandlePacket() {
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        MacAddress destMac = MacAddress.valueOf(OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS_DEFAULT);
+        MacAddress srcMac = MacAddress.valueOf("c6:b1:cd:40:dc:93");
+        String serialNumber = "switch-1";
+        final short ttlInSec = 120;
+        final short chasisId = 0;
+        String portName = "p0";
+        Ip4Address devIpAddr = Ip4Address.valueOf("192.168.1.1");
+        Ethernet packet = createLldpPacket(destMac, srcMac, chasisId, portName,
+                ttlInSec, serialNumber, devIpAddr.toString());
+
+        ConnectPoint cp = new ConnectPoint(d.id(), port.number());
+        sendInboundPacket(packet, cp);
+        // Need to have a delay before the validation as the packet processing now happens in a different thread
+        assertAfter(ASSERTION_DELAY, ASSERTION_LENGTH, () -> {
+            validateNeighborList(oltTopology.getNeighbours());
+        });
+        DeviceEvent portRem = deviceEvent(DeviceEvent.Type.PORT_REMOVED, DEVICE_ID_1, port);
+        deviceListener.event(portRem);
+        assertAfter(ASSERTION_DELAY, ASSERTION_LENGTH, () -> {
+            assertThat(oltTopology.getNeighbours().size(), is(0));
+        });
+    }
+
+    /**
+     * Testing Device Delete Scenario After Packet Handle for Packet in.
+     *
+     */
+    @Test
+    public void testDeviceDelAfterHandlePacket() {
+        Device d = oltTopology.deviceService.getDevice(DEVICE_ID_1);
+        Port port = new MockPort();
+        DeviceEvent portAdd = deviceEvent(DeviceEvent.Type.PORT_ADDED, DEVICE_ID_1, port);
+        deviceListener.event(portAdd);
+        MacAddress destMac = MacAddress.valueOf(OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS_DEFAULT);
+        MacAddress srcMac = MacAddress.valueOf("c6:b1:cd:40:dc:93");
+        String serialNumber = "switch-1";
+        final short ttlInSec = 120;
+        final short chasisId = 0;
+        String portName = "p0";
+        Ip4Address devIpAddr = Ip4Address.valueOf("192.168.1.1");
+        Ethernet packet = createLldpPacket(destMac, srcMac, chasisId, portName,
+                ttlInSec, serialNumber, devIpAddr.toString());
+
+        ConnectPoint cp = new ConnectPoint(d.id(), port.number());
+        sendInboundPacket(packet, cp);
+        assertAfter(ASSERTION_DELAY, ASSERTION_LENGTH, () -> {
+            validateNeighborList(oltTopology.getNeighbours());
+            assertThat(oltTopology.getNeighbours().size(), is(1));
+        });
+        DeviceEvent portRem = deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DEVICE_ID_1, port);
+        deviceListener.event(portRem);
+        assertAfter(ASSERTION_DELAY, ASSERTION_LENGTH, () -> {
+            assertThat(oltTopology.getNeighbours().size(), is(0));
+        });
+    }
+
+    /**
+     * Creates dummy packet for LLDP packet to test Packet in scenario.
+     *
+     * @param destMac    Destination Mac address of LLDP packet
+     * @param srcMac     Source mac address of LLDP packet
+     * @param chassisId  Chassis ID tlv value
+     * @param port       port Id tlv value
+     * @param ttl        TTL tlv value
+     * @param systemName System name tlv value
+     * @param mgmtAddr   Management Address tlv value
+     * @return LLDP ethernet packet
+     */
+    private Ethernet createLldpPacket(MacAddress destMac, MacAddress srcMac,
+                                      int chassisId, String port, short ttl,
+                                      String systemName, String mgmtAddr) {
+        Ethernet ethPkt = new Ethernet();
+        ethPkt.setEtherType(Ethernet.TYPE_LLDP);
+        ethPkt.setDestinationMACAddress(destMac);
+        ethPkt.setSourceMACAddress(srcMac);
+
+        LLDP lldpPkt = new LLDP();
+
+        setChassisId(lldpPkt, chassisId);
+        setPortId(lldpPkt, port);
+        setTtl(lldpPkt, ttl);
+
+        List<LLDPTLV> optionalTlv = new ArrayList<>();
+        optionalTlv.add(createSystemNameTlv(systemName));
+        optionalTlv.add(createMgmtAddressTlv(mgmtAddr));
+
+        lldpPkt.setOptionalTLVList(optionalTlv);
+
+        ethPkt.setPayload(lldpPkt);
+        return ethPkt;
+    }
+
+    /**
+     * Sets Chassis ID TLV for LLDP packet.
+     *
+     * @param lldpPkt   LLDP packet reference
+     * @param chassisId Chassid ID tlv value
+     */
+    private void setChassisId(LLDP lldpPkt, final int chassisId) {
+        final byte chassisTlvSubtype = 1;
+
+        byte[] chassis = ArrayUtils.addAll(new byte[]{chassisTlvSubtype},
+                ByteBuffer.allocate(String.valueOf(chassisId).length())
+                        .put(String.valueOf(chassisId).getBytes()).array());
+
+        LLDPTLV chassisTlv = new LLDPTLV();
+        lldpPkt.setChassisId(chassisTlv.setLength((byte) chassis.length)
+                .setType(LLDP.CHASSIS_TLV_TYPE)
+                .setValue(chassis));
+    }
+
+    /**
+     * Sets Port ID tlv for LLDP packet.
+     *
+     * @param lldpPkt   LLDP packet reference
+     * @param ifaceName Port Name TLV value
+     */
+    public void setPortId(LLDP lldpPkt, final String ifaceName) {
+        final byte portTlvSubtype = 5;
+
+        byte[] port = ArrayUtils.addAll(new byte[]{portTlvSubtype},
+                ifaceName.getBytes());
+
+        LLDPTLV portTlv = new LLDPTLV();
+        lldpPkt.setPortId(portTlv.setLength((byte) port.length)
+                .setType(LLDP.PORT_TLV_TYPE)
+                .setValue(port));
+    }
+
+    /**
+     * Sets  TTL tlv for LLDP packet.
+     *
+     * @param lldpPkt    LLDP Packet reference
+     * @param timeInSecs TTL tlv value in sec
+     */
+    public void setTtl(LLDP lldpPkt, final short timeInSecs) {
+        byte[] time = ByteBuffer.allocate(2).putShort(timeInSecs).array();
+        LLDPTLV ttlTlv = new LLDPTLV();
+        lldpPkt.setTtl(ttlTlv.setType(LLDP.TTL_TLV_TYPE)
+                .setLength((short) time.length)
+                .setValue(time));
+    }
+
+    /**
+     * Sets System name tlv for LLDP packet.
+     *
+     * @param systemName System name tlv value
+     * @return systemName tlv
+     */
+    public LLDPTLV createSystemNameTlv(String systemName) {
+        byte[] bytes = systemName.getBytes();
+        LLDPTLV sysNameTlv = new LLDPTLV();
+        return sysNameTlv.setType(SYSTEMNAME_TLV_TYPE)
+                .setLength((byte) bytes.length)
+                .setValue(bytes);
+    }
+
+    /**
+     * Sets Management address tlv for LLDP packet.
+     *
+     * @param mgmtAddress Management address tlv value
+     * @return Management address tlv
+     */
+    public LLDPTLV createMgmtAddressTlv(String mgmtAddress) {
+        final byte mgmtAddressTlvType = 0x8;
+        final byte ipAddressSubType = 0x1; // IPv4
+        // 5 below is address subtype + IP4 address len
+        final byte ipAddrStrLen = 0x5;
+        final byte interfaceSubtype = 0x1;
+        final int interfaceNum = 0;
+        final byte oidString = 0x0;
+        Ip4Address ipAddr = Ip4Address.valueOf(mgmtAddress);
+
+        byte[] addrStr = ArrayUtils.addAll(new byte[]{ipAddressSubType},
+                ipAddr.toOctets());
+
+        byte[] ipAddrBytes = ArrayUtils.addAll(new byte[]{ipAddrStrLen},
+                addrStr);
+        byte[] bytesInterfacetype = ArrayUtils.addAll(ipAddrBytes,
+                ByteBuffer.allocate(1).put(interfaceSubtype).array());
+        byte[] bytesInterfaceNumber = ArrayUtils.addAll(bytesInterfacetype,
+                ByteBuffer.allocate(4).putInt(interfaceNum).array());
+        byte[] finalMgmtAddrBytes = ArrayUtils.addAll(bytesInterfaceNumber,
+                ByteBuffer.allocate(1).put(oidString).array());
+
+        LLDPTLV mgmtAddrTlv = new LLDPTLV();
+        return mgmtAddrTlv.setType(mgmtAddressTlvType)
+                .setLength((byte) finalMgmtAddrBytes.length)
+                .setValue(finalMgmtAddrBytes);
+    }
+
+    /*
+    Mocks application id.
+     */
+    private static final class MockApplicationId implements ApplicationId {
+
+        private final short id;
+        private final String name;
+
+        public MockApplicationId(short id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        @Override
+        public short id() {
+            return id;
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+    }
+
+    /*
+    Mocks Core service adapter.
+     */
+    private static final class MockCoreService extends CoreServiceAdapter {
+
+        private List<ApplicationId> idList = new ArrayList<>();
+        private Map<String, ApplicationId> idMap = new HashMap<>();
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see
+         * org.onosproject.core.CoreServiceAdapter#getAppId(java.lang.Short)
+         */
+        @Override
+        public ApplicationId getAppId(Short id) {
+            if (id >= idList.size()) {
+                return null;
+            }
+            return idList.get(id);
+        }
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see
+         * org.onosproject.core.CoreServiceAdapter#getAppId(java.lang.String)
+         */
+        @Override
+        public ApplicationId getAppId(String name) {
+            return idMap.get(name);
+        }
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see
+         * org.onosproject.core.CoreServiceAdapter#registerApplication(java.lang
+         * .String)
+         */
+        @Override
+        public ApplicationId registerApplication(String name) {
+            ApplicationId appId = idMap.get(name);
+            if (appId == null) {
+                appId = new MockApplicationId((short) idList.size(), name);
+                idList.add(appId);
+                idMap.put(name, appId);
+            }
+            return appId;
+        }
+
+    }
+
+    private static class MockMastershipService extends MastershipServiceAdapter {
+        @Override
+        public boolean isLocalMaster(DeviceId d) {
+            return true;
+        }
+    }
+
+    private static class MockDevice extends DefaultDevice {
+
+        /*
+        Mocks OLT device.
+         */
+        public MockDevice(ProviderId providerId, DeviceId id, Type type,
+                          String manufacturer, String hwVersion, String swVersion,
+                          String serialNumber, ChassisId chassisId, Annotations... annotations) {
+            super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
+                    chassisId, annotations);
+        }
+    }
+
+    private static class MockSadisService implements SadisService {
+
+        @Override
+        public MockSubService getSubscriberInfoService() {
+            return new MockSubService();
+        }
+
+        @Override
+        public MockSubService getBandwidthProfileService() {
+            return new MockSubService();
+        }
+
+    }
+
+    /*
+     Mocks SubscriberAndDeviceInformationService(SADIS) information.
+      */
+    private static class MockSubService implements BaseInformationService {
+        MockSubscriberAndDeviceInformation device =
+                new MockSubscriberAndDeviceInformation(OLT_DEV_ID, VlanId.NONE, VlanId.NONE, null, null,
+                        OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"));
+        MockSubscriberAndDeviceInformation sub =
+                new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID, CLIENT_C_TAG,
+                        CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
+
+        @Override
+        public SubscriberAndDeviceInformation get(String id) {
+            if (id.equals(OLT_DEV_ID)) {
+                return device;
+            } else {
+                return sub;
+            }
+        }
+
+        @Override
+        public void invalidateAll() {
+        }
+
+        public void invalidateId(String id) {
+        }
+
+        public SubscriberAndDeviceInformation getfromCache(String id) {
+            return null;
+        }
+    }
+
+    /*
+    Mocks SubscriberAndDeviceInformation.
+     */
+    private static class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
+
+        MockSubscriberAndDeviceInformation(String id, VlanId ctag,
+                                           VlanId stag, String nasPortId,
+                                           String circuitId, MacAddress hardId,
+                                           Ip4Address ipAddress) {
+            UniTagInformation uniTagInformation = new UniTagInformation.Builder()
+                    .setPonCTag(ctag)
+                    .setPonSTag(stag)
+                    .build();
+            List<UniTagInformation> uniTagInformationList = Lists.newArrayList(uniTagInformation);
+            this.setUniTagList(uniTagInformationList);
+            // this.setCTag(ctag);
+            this.setHardwareIdentifier(hardId);
+            this.setId(id);
+            this.setIPAddress(ipAddress);
+//            this.setSTag(stag);
+            this.setNasPortId(nasPortId);
+            this.setCircuitId(circuitId);
+        }
+    }
+
+    private static class MockPort implements Port {
+
+        @Override
+        public boolean isEnabled() {
+            return true;
+        }
+
+        public long portSpeed() {
+            return 1000;
+        }
+
+        public Element element() {
+            return null;
+        }
+
+        public PortNumber number() {
+            return PortNumber.portNumber(1);
+        }
+
+        public Annotations annotations() {
+            return new MockAnnotations();
+        }
+
+        public Type type() {
+            return Port.Type.FIBER;
+        }
+
+        private static class MockAnnotations implements Annotations {
+
+            @Override
+            public String value(String val) {
+                return "nni-";
+            }
+
+            public Set<String> keys() {
+                return Sets.newHashSet("portName");
+            }
+        }
+    }
+
+    /*
+    Mocks Device Service Adapter.
+     */
+    private class MockDeviceService extends DeviceServiceAdapter {
+
+        private ProviderId providerId = new ProviderId("of", "foo");
+        private final Device device1 = new MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
+                "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
+                DEVICE_ANNOTATIONS);
+
+        @Override
+        public Device getDevice(DeviceId devId) {
+            return device1;
+
+        }
+
+        @Override
+        public Iterable<Device> getDevices() {
+            List<Device> devices = new ArrayList<>();
+            devices.add(device1);
+            return devices;
+        }
+
+        @Override
+        public Port getPort(ConnectPoint cp) {
+            return new MockPort();
+        }
+
+        @Override
+        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
+            return new MockPort();
+        }
+
+        @Override
+        public List<Port> getPorts(DeviceId deviceId) {
+            return Lists.newArrayList(new MockPort());
+        }
+
+        @Override
+        public boolean isAvailable(DeviceId d) {
+            return true;
+        }
+
+        @Override
+        public void addListener(DeviceListener listener) {
+            deviceListener = listener;
+        }
+
+        @Override
+        public void removeListener(DeviceListener listener) {
+
+        }
+    }
+}
diff --git a/app/src/test/java/org/opencord/olttopology/impl/OltTopologyTestBase.java b/app/src/test/java/org/opencord/olttopology/impl/OltTopologyTestBase.java
new file mode 100644
index 0000000..6dbfc5c
--- /dev/null
+++ b/app/src/test/java/org/opencord/olttopology/impl/OltTopologyTestBase.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.opencord.olttopology.impl;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.LLDP;
+import org.onlab.packet.LLDPTLV;
+import org.onlab.packet.MacAddress;
+
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.opencord.olttopology.OltNeighborInfo;
+import org.slf4j.Logger;
+
+import static org.junit.Assert.assertThat;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.fail;
+
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/*
+Olt topology test base class.
+ */
+public class OltTopologyTestBase {
+    private final Logger log = getLogger(getClass());
+
+    //Time in ms to wait before checking packets
+    static final int ASSERTION_DELAY = 250;
+    //Duration in ms of the assertion for packets
+    static final int ASSERTION_LENGTH = 250;
+
+    private static final String EXPECTED_IP = "10.10.10.10";
+    private static final String EXPECTED_OLT_DEV_ID = "of:0000c6b1cd40dc93";
+    private static final DeviceId EXPECTED_DEVICE_ID_1 = DeviceId.deviceId(EXPECTED_OLT_DEV_ID);
+
+
+
+    List<BasePacket> savedPackets = new LinkedList<>();
+    PacketProcessor packetProcessor;
+    MacAddress srcMac = MacAddress.valueOf("c6:b1:cd:40:dc:93");
+    MacAddress dstMac = MacAddress.valueOf(OsgiPropertyConstants.DEFAULT_DEST_MAC_ADDRESS_DEFAULT);
+
+
+    /**
+     * Saves the given packet onto the saved packets list.
+     *
+     * @param packet packet to save
+     */
+    void savePacket(BasePacket packet) {
+        savedPackets.add(packet);
+    }
+
+    /**
+     * Sends packet to Packer process to test Handle packet functionality.
+     * @param packet LLDP ethernet packet
+     * @param cp Device connect point info
+     */
+    void sendInboundPacket(Ethernet packet, ConnectPoint cp) {
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(packet.serialize());
+        InboundPacket inPacket = new DefaultInboundPacket(cp, packet, byteBuffer);
+        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+        packetProcessor.process(context);
+    }
+
+    /**
+     * Validates LLDP packet out functionality.
+     * @param responsePacket LLDP packet
+     */
+    void checkLldpPacket(Ethernet responsePacket) {
+     assertThat(responsePacket.getSourceMAC(), is(srcMac));
+     assertThat(responsePacket.getDestinationMAC(), is(dstMac));
+     assertThat(responsePacket.getPayload(), instanceOf(LLDP.class));
+     assertThat(responsePacket.getEtherType(), is(Ethernet.TYPE_LLDP));
+     LLDP lldp = (LLDP) responsePacket.getPayload();
+     assertThat(lldp, notNullValue());
+     assertThat(lldp.getPortId(), notNullValue());
+     String portName = "nni-";
+     byte[] port  = ArrayUtils.addAll(new byte[] {5}, portName.getBytes());
+     assertThat(lldp.getPortId().getValue(), is(port));
+     assertThat(lldp.getChassisId(), notNullValue());
+     int chassisId = 0;
+     byte[] chassis = ArrayUtils.addAll(new byte[] {1},
+             ByteBuffer.allocate(String.valueOf(chassisId).length())
+                     .put(String.valueOf(chassisId).getBytes()).array());
+     assertThat(lldp.getChassisId().getValue(), is(chassis));
+     assertThat(lldp.getTtl().getValue(), notNullValue());
+     short ttl = 120;
+     byte[] time = ByteBuffer.allocate(2).putShort(ttl).array();
+     assertThat(lldp.getTtl().getValue(), is(time));
+     assertThat(lldp.getOptionalTLVList(), notNullValue());
+     List<LLDPTLV> optionalTlvs = lldp.getOptionalTLVList();
+     for (LLDPTLV tlv: optionalTlvs) {
+         if (tlv.getType() == OltTopology.SYSTEMNAME_TLV_TYPE) {
+             assertThat(tlv.getValue(), notNullValue());
+             String[] systemName = EXPECTED_DEVICE_ID_1.toString().split(":", 2);
+             byte[] deviceId = systemName[1].getBytes();
+             assertThat(tlv.getValue(), is(deviceId));
+         } else if (tlv.getType() == OltTopology.MANAGEMENT_ADDR_TLV_TYPE) {
+             assertThat(tlv.getValue(), notNullValue());
+             final byte ipAddressSubType = 0x1; // IPv4
+             // 5 below is address subtype + IP4 address len
+             final byte ipAddrStrLen = 0x5;
+             final byte interfaceSubtype = 0x1;
+             final int interfaceNum = 0;
+             final byte oidString = 0x0;
+             Ip4Address ipAddr = Ip4Address.valueOf(EXPECTED_IP);
+
+             byte[] addrStr =  ArrayUtils.addAll(new byte[] {ipAddressSubType},
+                     ipAddr.toOctets());
+
+             byte[] ipAddrBytes =  ArrayUtils.addAll(new byte[] {ipAddrStrLen},
+                     addrStr);
+             byte[] bytesInterfacetype = ArrayUtils.addAll(ipAddrBytes,
+                     ByteBuffer.allocate(1).put(interfaceSubtype).array());
+             byte[] bytesInterfaceNumber = ArrayUtils.addAll(bytesInterfacetype,
+                     ByteBuffer.allocate(4).putInt(interfaceNum).array());
+             byte[] finalMgmtAddrBytes = ArrayUtils.addAll(bytesInterfaceNumber,
+                     ByteBuffer.allocate(1).put(oidString).array());
+             assertThat(tlv.getValue(), is(finalMgmtAddrBytes));
+
+         }
+     }
+    }
+
+    /**
+     * Validates Neightbour list table.
+     * @param neighborList Neighbour list table created using inbound LLDP packets.
+     */
+    void validateNeighborList(Map<ConnectPoint, OltNeighborInfo> neighborList) {
+        assertThat(neighborList, notNullValue());
+        assertThat(neighborList.size(), is(1));
+        for (Map.Entry<ConnectPoint, OltNeighborInfo> entry: neighborList.entrySet()) {
+            assertThat(entry.getValue().mgmtAddr(), is("192.168.1.1"));
+            assertThat(entry.getValue().neighborName(), is("switch-1"));
+            assertThat(entry.getValue().neighborPort(), is("p0"));
+            assertThat(entry.getValue().oltName(), is("0000c6b1cd40dc93"));
+            assertThat(entry.getValue().oltPort().annotations().value("portName"), is("nni-"));
+        }
+    }
+    /**
+     * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
+     */
+    class MockPacketService extends PacketServiceAdapter {
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            try {
+                Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
+                        0, packet.data().array().length);
+                savePacket(eth);
+            } catch (Exception e) {
+                fail(e.getMessage());
+            }
+        }
+    }
+    /**
+     * Mock Flow Objective Service.
+     */
+    public static class MockFlowObjectiveService extends FlowObjectiveServiceAdapter {
+
+        @Override
+        public void filter(DeviceId deviceId, FilteringObjective filter) {
+            assertThat(deviceId, notNullValue());
+            assertThat(filter, notNullValue());
+            EthTypeCriterion ethType = (EthTypeCriterion)
+                    filterForCriterion(filter.conditions(), Criterion.Type.ETH_TYPE);
+            assertThat(ethType, notNullValue());
+            assertThat(ethType.ethType(), is(EthType.EtherType.LLDP.ethType()));
+            assertThat(filter.key().type(), is(Criterion.Type.IN_PORT));
+
+        }
+        private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) {
+            return criteria.stream()
+                    .filter(c -> c.type().equals(type))
+                    .limit(1)
+                    .findFirst().orElse(null);
+        }
+
+    }
+    /**
+     * Mocks the DefaultPacketContext.
+     */
+    static final class TestPacketContext extends DefaultPacketContext {
+
+        private TestPacketContext(long time, InboundPacket inPkt,
+                                  OutboundPacket outPkt, boolean block) {
+            super(time, inPkt, outPkt, block);
+        }
+
+        @Override
+        public void send() {
+            // We don't send anything out.
+        }
+    }
+}
diff --git a/app/src/test/java/org/opencord/olttopology/impl/package-info.java b/app/src/test/java/org/opencord/olttopology/impl/package-info.java
new file mode 100755
index 0000000..7104a76
--- /dev/null
+++ b/app/src/test/java/org/opencord/olttopology/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * OLT Topology application for finding the topology of OLTs.
+ */
+package org.opencord.olttopology.impl;
