diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go
new file mode 100644
index 0000000..0095575
--- /dev/null
+++ b/internal/pkg/config/config.go
@@ -0,0 +1,200 @@
+/*
+* 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 config provides the Log, kvstore, Kafka configuration
+package config
+
+import (
+	"flag"
+	"fmt"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"os"
+	"time"
+)
+
+// Open OLT default constants
+const (
+	EtcdStoreName               = "etcd"
+	defaultInstanceid           = "openOlt001"
+	defaultKafkaadapterhost     = "127.0.0.1"
+	defaultKafkaadapterport     = 9092
+	defaultKafkaclusterhost     = "127.0.0.1"
+	defaultKafkaclusterport     = 9094
+	defaultKvstoretype          = EtcdStoreName
+	defaultKvstoretimeout       = 5 //in seconds
+	defaultKvstorehost          = "127.0.0.1"
+	defaultKvstoreport          = 2379 // Consul = 8500; Etcd = 2379
+	defaultLoglevel             = "DEBUG"
+	defaultBanner               = false
+	defaultDisplayVersionOnly   = false
+	defaultTopic                = "openolt"
+	defaultCoretopic            = "rwcore"
+	defaultEventtopic           = "voltha.events"
+	defaultOnunumber            = 1
+	defaultProbeHost            = ""
+	defaultProbePort            = 8080
+	defaultLiveProbeInterval    = 60 * time.Second
+	defaultNotLiveProbeInterval = 5 * time.Second // Probe more frequently when not alive
+	//defaultHearbeatFailReportInterval is the time in seconds the adapter will keep checking the hardware for heartbeat.
+	defaultHearbeatCheckInterval = 30 * time.Second
+	// defaultHearbeatFailReportInterval is the time adapter will wait before updating the state to the core.
+	defaultHearbeatFailReportInterval = 180 * time.Second
+	//defaultGrpcTimeoutInterval is the time in seconds a grpc call will wait before returning error.
+	defaultGrpcTimeoutInterval = 2 * time.Second
+)
+
+// AdapterFlags represents the set of configurations used by the read-write adaptercore service
+type AdapterFlags struct {
+	// Command line parameters
+	InstanceID                  string
+	KafkaAdapterHost            string
+	KafkaAdapterPort            int
+	KafkaClusterHost            string
+	KafkaClusterPort            int
+	KVStoreType                 string
+	KVStoreTimeout              int // in seconds
+	KVStoreHost                 string
+	KVStorePort                 int
+	Topic                       string
+	CoreTopic                   string
+	EventTopic                  string
+	LogLevel                    string
+	OnuNumber                   int
+	Banner                      bool
+	DisplayVersionOnly          bool
+	ProbeHost                   string
+	ProbePort                   int
+	LiveProbeInterval           time.Duration
+	NotLiveProbeInterval        time.Duration
+	HeartbeatCheckInterval      time.Duration
+	HeartbeatFailReportInterval time.Duration
+	GrpcTimeoutInterval         time.Duration
+}
+
+func init() {
+	_, _ = log.AddPackage(log.JSON, log.WarnLevel, nil)
+}
+
+// NewAdapterFlags returns a new RWCore config
+func NewAdapterFlags() *AdapterFlags {
+	var adapterFlags = AdapterFlags{ // Default values
+		InstanceID:                  defaultInstanceid,
+		KafkaAdapterHost:            defaultKafkaadapterhost,
+		KafkaAdapterPort:            defaultKafkaadapterport,
+		KafkaClusterHost:            defaultKafkaclusterhost,
+		KafkaClusterPort:            defaultKafkaclusterport,
+		KVStoreType:                 defaultKvstoretype,
+		KVStoreTimeout:              defaultKvstoretimeout,
+		KVStoreHost:                 defaultKvstorehost,
+		KVStorePort:                 defaultKvstoreport,
+		Topic:                       defaultTopic,
+		CoreTopic:                   defaultCoretopic,
+		EventTopic:                  defaultEventtopic,
+		LogLevel:                    defaultLoglevel,
+		OnuNumber:                   defaultOnunumber,
+		Banner:                      defaultBanner,
+		DisplayVersionOnly:          defaultDisplayVersionOnly,
+		ProbeHost:                   defaultProbeHost,
+		ProbePort:                   defaultProbePort,
+		LiveProbeInterval:           defaultLiveProbeInterval,
+		NotLiveProbeInterval:        defaultNotLiveProbeInterval,
+		HeartbeatCheckInterval:      defaultHearbeatCheckInterval,
+		HeartbeatFailReportInterval: defaultHearbeatFailReportInterval,
+		GrpcTimeoutInterval:         defaultGrpcTimeoutInterval,
+	}
+	return &adapterFlags
+}
+
+// ParseCommandArguments parses the arguments when running read-write adaptercore service
+func (so *AdapterFlags) ParseCommandArguments() {
+
+	help := fmt.Sprintf("Kafka - Adapter messaging host")
+	flag.StringVar(&(so.KafkaAdapterHost), "kafka_adapter_host", defaultKafkaadapterhost, help)
+
+	help = fmt.Sprintf("Kafka - Adapter messaging port")
+	flag.IntVar(&(so.KafkaAdapterPort), "kafka_adapter_port", defaultKafkaadapterport, help)
+
+	help = fmt.Sprintf("Kafka - Cluster messaging host")
+	flag.StringVar(&(so.KafkaClusterHost), "kafka_cluster_host", defaultKafkaclusterhost, help)
+
+	help = fmt.Sprintf("Kafka - Cluster messaging port")
+	flag.IntVar(&(so.KafkaClusterPort), "kafka_cluster_port", defaultKafkaclusterport, help)
+
+	help = fmt.Sprintf("Open OLT topic")
+	flag.StringVar(&(so.Topic), "adapter_topic", defaultTopic, help)
+
+	help = fmt.Sprintf("Core topic")
+	flag.StringVar(&(so.CoreTopic), "core_topic", defaultCoretopic, help)
+
+	help = fmt.Sprintf("Event topic")
+	flag.StringVar(&(so.EventTopic), "event_topic", defaultEventtopic, help)
+
+	help = fmt.Sprintf("KV store type")
+	flag.StringVar(&(so.KVStoreType), "kv_store_type", defaultKvstoretype, help)
+
+	help = fmt.Sprintf("The default timeout when making a kv store request")
+	flag.IntVar(&(so.KVStoreTimeout), "kv_store_request_timeout", defaultKvstoretimeout, help)
+
+	help = fmt.Sprintf("KV store host")
+	flag.StringVar(&(so.KVStoreHost), "kv_store_host", defaultKvstorehost, help)
+
+	help = fmt.Sprintf("KV store port")
+	flag.IntVar(&(so.KVStorePort), "kv_store_port", defaultKvstoreport, help)
+
+	help = fmt.Sprintf("Log level")
+	flag.StringVar(&(so.LogLevel), "log_level", defaultLoglevel, help)
+
+	help = fmt.Sprintf("Number of ONUs")
+	flag.IntVar(&(so.OnuNumber), "onu_number", defaultOnunumber, help)
+
+	help = fmt.Sprintf("Show startup banner log lines")
+	flag.BoolVar(&(so.Banner), "banner", defaultBanner, help)
+
+	help = fmt.Sprintf("Show version information and exit")
+	flag.BoolVar(&(so.DisplayVersionOnly), "version", defaultDisplayVersionOnly, help)
+
+	help = fmt.Sprintf("The address on which to listen to answer liveness and readiness probe queries over HTTP.")
+	flag.StringVar(&(so.ProbeHost), "probe_host", defaultProbeHost, help)
+
+	help = fmt.Sprintf("The port on which to listen to answer liveness and readiness probe queries over HTTP.")
+	flag.IntVar(&(so.ProbePort), "probe_port", defaultProbePort, help)
+
+	help = fmt.Sprintf("Number of seconds for the default liveliness check")
+	flag.DurationVar(&(so.LiveProbeInterval), "live_probe_interval", defaultLiveProbeInterval, help)
+
+	help = fmt.Sprintf("Number of seconds for liveliness check if probe is not running")
+	flag.DurationVar(&(so.NotLiveProbeInterval), "not_live_probe_interval", defaultNotLiveProbeInterval, help)
+
+	help = fmt.Sprintf("Number of seconds for heartbeat check interval.")
+	flag.DurationVar(&(so.HeartbeatCheckInterval), "hearbeat_check_interval", defaultHearbeatCheckInterval, help)
+
+	help = fmt.Sprintf("Number of seconds adapter has to wait before reporting core on the hearbeat check failure.")
+	flag.DurationVar(&(so.HeartbeatFailReportInterval), "hearbeat_fail_interval", defaultHearbeatFailReportInterval, help)
+
+	help = fmt.Sprintf("Number of seconds for GRPC timeout.")
+	flag.DurationVar(&(so.GrpcTimeoutInterval), "grpc_timeout_interval", defaultGrpcTimeoutInterval, help)
+
+	flag.Parse()
+	containerName := getContainerInfo()
+	if len(containerName) > 0 {
+		so.InstanceID = containerName
+	}
+
+}
+
+func getContainerInfo() string {
+	return os.Getenv("HOSTNAME")
+}
diff --git a/internal/pkg/config/config_test.go b/internal/pkg/config/config_test.go
new file mode 100644
index 0000000..332b9ea
--- /dev/null
+++ b/internal/pkg/config/config_test.go
@@ -0,0 +1,25 @@
+/*
+ * 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 config provides the Log, kvstore, Kafka configuration
+package config
+
+import "testing"
+
+func TestAdapterFlags_ParseCommandArguments(t *testing.T) {
+	so := NewAdapterFlags()
+	so.ParseCommandArguments()
+}
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
new file mode 100644
index 0000000..0695af6
--- /dev/null
+++ b/internal/pkg/core/device_handler.go
@@ -0,0 +1,1828 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"encoding/hex"
+	"fmt"
+	"io"
+	"net"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"google.golang.org/grpc/codes"
+
+	"github.com/cenkalti/backoff/v3"
+	"github.com/gogo/protobuf/proto"
+	"github.com/golang/protobuf/ptypes"
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
+	rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
+	"github.com/opencord/voltha-protos/v3/go/common"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	of "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	oop "github.com/opencord/voltha-protos/v3/go/openolt"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/status"
+)
+
+// Constants for number of retries and for timeout
+const (
+	MaxRetry       = 10
+	MaxTimeOutInMs = 500
+)
+
+//DeviceHandler will interact with the OLT device.
+type DeviceHandler struct {
+	deviceID      string
+	deviceType    string
+	adminState    string
+	device        *voltha.Device
+	coreProxy     adapterif.CoreProxy
+	AdapterProxy  adapterif.AdapterProxy
+	EventProxy    adapterif.EventProxy
+	openOLT       *OpenOLT
+	exitChannel   chan int
+	lockDevice    sync.RWMutex
+	Client        oop.OpenoltClient
+	transitionMap *TransitionMap
+	clientCon     *grpc.ClientConn
+	flowMgr       *OpenOltFlowMgr
+	eventMgr      *OpenOltEventMgr
+	resourceMgr   *rsrcMgr.OpenOltResourceMgr
+
+	discOnus           sync.Map
+	onus               sync.Map
+	portStats          *OpenOltStatisticsMgr
+	metrics            *pmmetrics.PmMetrics
+	stopCollector      chan bool
+	stopHeartbeatCheck chan bool
+	activePorts        sync.Map
+}
+
+//OnuDevice represents ONU related info
+type OnuDevice struct {
+	deviceID      string
+	deviceType    string
+	serialNumber  string
+	onuID         uint32
+	intfID        uint32
+	proxyDeviceID string
+	uniPorts      map[uint32]struct{}
+}
+
+var pmNames = []string{
+	"rx_bytes",
+	"rx_packets",
+	"rx_mcast_packets",
+	"rx_bcast_packets",
+	"tx_bytes",
+	"tx_packets",
+	"tx_mcast_packets",
+	"tx_bcast_packets",
+}
+
+//NewOnuDevice creates a new Onu Device
+func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string) *OnuDevice {
+	var device OnuDevice
+	device.deviceID = devID
+	device.deviceType = deviceTp
+	device.serialNumber = serialNum
+	device.onuID = onuID
+	device.intfID = intfID
+	device.proxyDeviceID = proxyDevID
+	device.uniPorts = make(map[uint32]struct{})
+	return &device
+}
+
+//NewDeviceHandler creates a new device handler
+func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
+	var dh DeviceHandler
+	dh.coreProxy = cp
+	dh.AdapterProxy = ap
+	dh.EventProxy = ep
+	cloned := (proto.Clone(device)).(*voltha.Device)
+	dh.deviceID = cloned.Id
+	dh.deviceType = cloned.Type
+	dh.adminState = "up"
+	dh.device = cloned
+	dh.openOLT = adapter
+	dh.exitChannel = make(chan int, 1)
+	dh.lockDevice = sync.RWMutex{}
+	dh.stopCollector = make(chan bool, 2)
+	dh.stopHeartbeatCheck = make(chan bool, 2)
+	dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
+	dh.activePorts = sync.Map{}
+	//TODO initialize the support classes.
+	return &dh
+}
+
+// start save the device to the data model
+func (dh *DeviceHandler) start(ctx context.Context) {
+	dh.lockDevice.Lock()
+	defer dh.lockDevice.Unlock()
+	log.Debugw("starting-device-agent", log.Fields{"device": dh.device})
+	// Add the initial device to the local model
+	log.Debug("device-agent-started")
+}
+
+// stop stops the device dh.  Not much to do for now
+func (dh *DeviceHandler) stop(ctx context.Context) {
+	dh.lockDevice.Lock()
+	defer dh.lockDevice.Unlock()
+	log.Debug("stopping-device-agent")
+	dh.exitChannel <- 1
+	log.Debug("device-agent-stopped")
+}
+
+func macifyIP(ip net.IP) string {
+	if len(ip) > 0 {
+		oct1 := strconv.FormatInt(int64(ip[12]), 16)
+		oct2 := strconv.FormatInt(int64(ip[13]), 16)
+		oct3 := strconv.FormatInt(int64(ip[14]), 16)
+		oct4 := strconv.FormatInt(int64(ip[15]), 16)
+		return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
+	}
+	return ""
+}
+
+func generateMacFromHost(host string) (string, error) {
+	var genmac string
+	var addr net.IP
+	var ips []string
+	var err error
+
+	log.Debugw("generating-mac-from-host", log.Fields{"host": host})
+
+	if addr = net.ParseIP(host); addr == nil {
+		log.Debugw("looking-up-hostname", log.Fields{"host": host})
+
+		if ips, err = net.LookupHost(host); err == nil {
+			log.Debugw("dns-result-ips", log.Fields{"ips": ips})
+			if addr = net.ParseIP(ips[0]); addr == nil {
+				return "", NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil).Log()
+			}
+			genmac = macifyIP(addr)
+			log.Debugw("using-ip-as-mac", log.Fields{"host": ips[0], "mac": genmac})
+			return genmac, nil
+		}
+		return "", NewErrAdapter("cannot-resolve-hostname-to-ip", nil, err).Log()
+	}
+
+	genmac = macifyIP(addr)
+	log.Debugw("using-ip-as-mac", log.Fields{"host": host, "mac": genmac})
+	return genmac, nil
+}
+
+func macAddressToUint32Array(mac string) []uint32 {
+	slist := strings.Split(mac, ":")
+	result := make([]uint32, len(slist))
+	var err error
+	var tmp int64
+	for index, val := range slist {
+		if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
+			return []uint32{1, 2, 3, 4, 5, 6}
+		}
+		result[index] = uint32(tmp)
+	}
+	return result
+}
+
+//GetportLabel returns the label for the NNI and the PON port based on port number and port type
+func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
+
+	switch portType {
+	case voltha.Port_ETHERNET_NNI:
+		return fmt.Sprintf("nni-%d", portNum), nil
+	case voltha.Port_PON_OLT:
+		return fmt.Sprintf("pon-%d", portNum), nil
+	}
+
+	return "", NewErrInvalidValue(log.Fields{"port-type": portType}, nil).Log()
+}
+
+func (dh *DeviceHandler) addPort(intfID uint32, portType voltha.Port_PortType, state string) error {
+	var operStatus common.OperStatus_Types
+	if state == "up" {
+		operStatus = voltha.OperStatus_ACTIVE
+		//populating the intfStatus map
+		dh.activePorts.Store(intfID, true)
+	} else {
+		operStatus = voltha.OperStatus_DISCOVERED
+		dh.activePorts.Store(intfID, false)
+	}
+	portNum := IntfIDToPortNo(intfID, portType)
+	label, err := GetportLabel(portNum, portType)
+	if err != nil {
+		return NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, nil).Log()
+	}
+
+	device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
+	if err != nil || device == nil {
+		return NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+	if device.Ports != nil {
+		for _, dPort := range device.Ports {
+			if dPort.Type == portType && dPort.PortNo == portNum {
+				log.Debug("port-already-exists-updating-oper-status-of-port")
+				if err := dh.coreProxy.PortStateUpdate(context.TODO(), dh.device.Id, portType, portNum, operStatus); err != nil {
+					return NewErrAdapter("failed-to-update-port-state", log.Fields{
+						"device-id":   dh.device.Id,
+						"port-type":   portType,
+						"port-number": portNum,
+						"oper-status": operStatus}, err).Log()
+
+				}
+				return nil
+			}
+		}
+	}
+	//    Now create  Port
+	port := &voltha.Port{
+		PortNo:     portNum,
+		Label:      label,
+		Type:       portType,
+		OperStatus: operStatus,
+	}
+	log.Debugw("Sending-port-update-to-core", log.Fields{"port": port})
+	// Synchronous call to update device - this method is run in its own go routine
+	if err := dh.coreProxy.PortCreated(context.TODO(), dh.device.Id, port); err != nil {
+		return NewErrAdapter("Error-creating-port", log.Fields{
+			"device-id": dh.device.Id,
+			"port-type": portType}, err).Log()
+	}
+	return nil
+}
+
+// readIndications to read the indications from the OLT device
+func (dh *DeviceHandler) readIndications(ctx context.Context) error {
+	defer log.Debugw("indications-ended", log.Fields{"device-id": dh.device.Id})
+	indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
+	if err != nil {
+		return NewErrCommunication("fail-to-read-indications", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+	if indications == nil {
+		return NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
+	}
+	/* get device state */
+	device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
+	if err != nil || device == nil {
+		/*TODO: needs to handle error scenarios */
+		return NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+	// When the device is in DISABLED and Adapter container restarts, we need to
+	// rebuild the locally maintained admin state.
+	if device.AdminState == voltha.AdminState_DISABLED {
+		dh.lockDevice.Lock()
+		dh.adminState = "down"
+		dh.lockDevice.Unlock()
+	}
+
+	// Create an exponential backoff around re-enabling indications. The
+	// maximum elapsed time for the back off is set to 0 so that we will
+	// continue to retry. The max interval defaults to 1m, but is set
+	// here for code clarity
+	indicationBackoff := backoff.NewExponentialBackOff()
+	indicationBackoff.MaxElapsedTime = 0
+	indicationBackoff.MaxInterval = 1 * time.Minute
+	for {
+		indication, err := indications.Recv()
+		if err == io.EOF {
+			log.Infow("EOF for  indications", log.Fields{"err": err})
+			// Use an exponential back off to prevent getting into a tight loop
+			duration := indicationBackoff.NextBackOff()
+			if duration == backoff.Stop {
+				// If we reach a maximum then warn and reset the backoff
+				// timer and keep attempting.
+				log.Warnw("Maximum indication backoff reached, resetting backoff timer",
+					log.Fields{"max_indication_backoff": indicationBackoff.MaxElapsedTime})
+				indicationBackoff.Reset()
+			}
+			time.Sleep(indicationBackoff.NextBackOff())
+			indications, err = dh.Client.EnableIndication(ctx, new(oop.Empty))
+			if err != nil {
+				return NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
+			}
+			continue
+		}
+		if err != nil {
+			log.Infow("Failed to read from indications", log.Fields{"err": err})
+			if dh.adminState == "deleted" {
+				log.Debug("Device deleted stoping the read indication thread")
+				break
+			}
+			dh.transitionMap.Handle(ctx, DeviceDownInd)
+			dh.transitionMap.Handle(ctx, DeviceInit)
+			return NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
+		}
+		// Reset backoff if we have a successful receive
+		indicationBackoff.Reset()
+		dh.lockDevice.RLock()
+		adminState := dh.adminState
+		dh.lockDevice.RUnlock()
+		// When OLT is admin down, ignore all indications.
+		if adminState == "down" {
+
+			log.Infow("olt is admin down, ignore indication", log.Fields{"indication": indication})
+			continue
+		}
+		dh.handleIndication(ctx, indication)
+
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
+	raisedTs := time.Now().UnixNano()
+	if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
+		dh.transitionMap.Handle(ctx, DeviceUpInd)
+	} else if oltIndication.OperState == "down" {
+		dh.transitionMap.Handle(ctx, DeviceDownInd)
+	}
+	// Send or clear Alarm
+	if err := dh.eventMgr.oltUpDownIndication(oltIndication, dh.deviceID, raisedTs); err != nil {
+		return NewErrAdapter("failed-indication", log.Fields{
+			"device_id":  dh.deviceID,
+			"indication": oltIndication,
+			"timestamp":  raisedTs}, err).Log()
+	}
+	return nil
+}
+
+// nolint: gocyclo
+func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
+	raisedTs := time.Now().UnixNano()
+	switch indication.Data.(type) {
+	case *oop.Indication_OltInd:
+		if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
+			NewErrAdapter("handle-indication-error", log.Fields{"type": "olt"}, err).Log()
+		}
+	case *oop.Indication_IntfInd:
+		intfInd := indication.GetIntfInd()
+		go func() {
+			if err := dh.addPort(intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
+				NewErrAdapter("handle-indication-error", log.Fields{"type": "interface"}, err).Log()
+			}
+		}()
+		log.Infow("Received interface indication ", log.Fields{"InterfaceInd": intfInd})
+	case *oop.Indication_IntfOperInd:
+		intfOperInd := indication.GetIntfOperInd()
+		if intfOperInd.GetType() == "nni" {
+			go func() {
+				if err := dh.addPort(intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
+					NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni"}, err).Log()
+				}
+			}()
+			dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId())
+		} else if intfOperInd.GetType() == "pon" {
+			// TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
+			// Handle pon port update
+			go func() {
+				if err := dh.addPort(intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
+					NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon"}, err).Log()
+				}
+			}()
+			go dh.eventMgr.oltIntfOperIndication(indication.GetIntfOperInd(), dh.deviceID, raisedTs)
+		}
+		log.Infow("Received interface oper indication ", log.Fields{"InterfaceOperInd": intfOperInd})
+	case *oop.Indication_OnuDiscInd:
+		onuDiscInd := indication.GetOnuDiscInd()
+		log.Infow("Received Onu discovery indication ", log.Fields{"OnuDiscInd": onuDiscInd})
+		sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
+		go func() {
+			if err := dh.onuDiscIndication(ctx, onuDiscInd, sn); err != nil {
+				NewErrAdapter("handle-indication-error", log.Fields{"type": "onu-discovery"}, err).Log()
+			}
+		}()
+	case *oop.Indication_OnuInd:
+		onuInd := indication.GetOnuInd()
+		log.Infow("Received Onu indication ", log.Fields{"OnuInd": onuInd})
+		go func() {
+			if err := dh.onuIndication(onuInd); err != nil {
+				NewErrAdapter("handle-indication-error", log.Fields{"type": "onu"}, err).Log()
+			}
+		}()
+	case *oop.Indication_OmciInd:
+		omciInd := indication.GetOmciInd()
+		log.Debugw("Received Omci indication ", log.Fields{"IntfId": omciInd.IntfId, "OnuId": omciInd.OnuId, "pkt": hex.EncodeToString(omciInd.Pkt)})
+		go func() {
+			if err := dh.omciIndication(omciInd); err != nil {
+				NewErrAdapter("handle-indication-error", log.Fields{"type": "omci"}, err).Log()
+			}
+		}()
+	case *oop.Indication_PktInd:
+		pktInd := indication.GetPktInd()
+		log.Infow("Received pakcet indication ", log.Fields{"PktInd": pktInd})
+		go func() {
+			if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
+				NewErrAdapter("handle-indication-error", log.Fields{"type": "packet"}, err).Log()
+			}
+		}()
+	case *oop.Indication_PortStats:
+		portStats := indication.GetPortStats()
+		go dh.portStats.PortStatisticsIndication(portStats, dh.resourceMgr.DevInfo.GetPonPorts())
+	case *oop.Indication_FlowStats:
+		flowStats := indication.GetFlowStats()
+		log.Infow("Received flow stats", log.Fields{"FlowStats": flowStats})
+	case *oop.Indication_AlarmInd:
+		alarmInd := indication.GetAlarmInd()
+		log.Infow("Received alarm indication ", log.Fields{"AlarmInd": alarmInd})
+		go dh.eventMgr.ProcessEvents(alarmInd, dh.deviceID, raisedTs)
+	}
+}
+
+// doStateUp handle the olt up indication and update to voltha core
+func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
+	// Synchronous call to update device state - this method is run in its own go routine
+	if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
+		voltha.OperStatus_ACTIVE); err != nil {
+		return NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+	return nil
+}
+
+// doStateDown handle the olt down indication
+func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
+	dh.lockDevice.Lock()
+	defer dh.lockDevice.Unlock()
+	log.Debug("do-state-down-start")
+
+	device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
+	if err != nil || device == nil {
+		/*TODO: needs to handle error scenarios */
+		return NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+
+	cloned := proto.Clone(device).(*voltha.Device)
+	// Update the all ports state on that device to disable
+	if err = dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
+		return NewErrAdapter("port-update-failed", log.Fields{"device-id": device.Id}, err).Log()
+	}
+
+	//Update the device oper state and connection status
+	cloned.OperStatus = voltha.OperStatus_UNKNOWN
+	cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
+	dh.device = cloned
+
+	if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
+		return NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err).Log()
+	}
+
+	//get the child device for the parent device
+	onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
+	if err != nil {
+		return NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+	for _, onuDevice := range onuDevices.Items {
+
+		// Update onu state as down in onu adapter
+		onuInd := oop.OnuIndication{}
+		onuInd.OperState = "down"
+		err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
+			"openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
+		if err != nil {
+			NewErrCommunication("inter-adapter-send-failed", log.Fields{
+				"source":        "openolt",
+				"onu-indicator": onuInd,
+				"device-type":   onuDevice.Type,
+				"device-id":     onuDevice.Id}, err).LogAt(log.ErrorLevel)
+			//Do not return here and continue to process other ONUs
+		}
+	}
+	/* Discovered ONUs entries need to be cleared , since after OLT
+	   is up, it starts sending discovery indications again*/
+	dh.discOnus = sync.Map{}
+	log.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
+	return nil
+}
+
+// doStateInit dial the grpc before going to init state
+func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
+	var err error
+	if dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock()); err != nil {
+		return NewErrCommunication("dial-failure", log.Fields{
+			"device-id":     dh.deviceID,
+			"host-and-port": dh.device.GetHostAndPort()}, err).Log()
+	}
+	return nil
+}
+
+// postInit create olt client instance to invoke RPC on the olt device
+func (dh *DeviceHandler) postInit(ctx context.Context) error {
+	dh.Client = oop.NewOpenoltClient(dh.clientCon)
+	dh.transitionMap.Handle(ctx, GrpcConnected)
+	return nil
+}
+
+// doStateConnected get the device info and update to voltha core
+func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
+	log.Debug("OLT device has been connected")
+
+	// Case where OLT is disabled and then rebooted.
+	if dh.adminState == "down" {
+		log.Debugln("do-state-connected--device-admin-state-down")
+		device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
+		if err != nil || device == nil {
+			/*TODO: needs to handle error scenarios */
+			NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
+		}
+
+		cloned := proto.Clone(device).(*voltha.Device)
+		cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
+		cloned.OperStatus = voltha.OperStatus_UNKNOWN
+		dh.device = cloned
+		if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
+			NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
+		}
+
+		// Since the device was disabled before the OLT was rebooted, enforce the OLT to be Disabled after re-connection.
+		_, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
+		if err != nil {
+			NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
+		}
+
+		// Start reading indications
+		go func() {
+			if err := dh.readIndications(ctx); err != nil {
+				NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
+			}
+		}()
+		return nil
+	}
+
+	deviceInfo, err := dh.populateDeviceInfo()
+	if err != nil {
+		return NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+
+	device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
+	if err != nil || device == nil {
+		/*TODO: needs to handle error scenarios */
+		return NewErrAdapter("fetch-device-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+	dh.populateActivePorts(device)
+	if err := dh.disableAdminDownPorts(device); err != nil {
+		return NewErrAdapter("port-status-update-failed", log.Fields{"device": device}, err).Log()
+	}
+
+	KVStoreHostPort := fmt.Sprintf("%s:%d", dh.openOLT.KVStoreHost, dh.openOLT.KVStorePort)
+	// Instantiate resource manager
+	if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.deviceID, KVStoreHostPort, dh.openOLT.KVStoreType, dh.deviceType, deviceInfo); dh.resourceMgr == nil {
+		return ErrResourceManagerInstantiating.Log()
+	}
+	// Instantiate flow manager
+	if dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr); dh.flowMgr == nil {
+		return ErrResourceManagerInstantiating.Log()
+	}
+	/* TODO: Instantiate Alarm , stats , BW managers */
+	/* Instantiating Event Manager to handle Alarms and KPIs */
+	dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
+	// Stats config for new device
+	dh.portStats = NewOpenOltStatsMgr(dh)
+
+	// Start reading indications
+	go func() {
+		if err := dh.readIndications(ctx); err != nil {
+			NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
+		}
+	}()
+	return nil
+}
+
+func (dh *DeviceHandler) populateDeviceInfo() (*oop.DeviceInfo, error) {
+	var err error
+	var deviceInfo *oop.DeviceInfo
+
+	deviceInfo, err = dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
+
+	if err != nil {
+		return nil, NewErrPersistence("get", "device", 0, nil, err).Log()
+	}
+	if deviceInfo == nil {
+		return nil, NewErrInvalidValue(log.Fields{"device": nil}, nil).Log()
+	}
+
+	log.Debugw("Fetched device info", log.Fields{"deviceInfo": deviceInfo})
+	dh.device.Root = true
+	dh.device.Vendor = deviceInfo.Vendor
+	dh.device.Model = deviceInfo.Model
+	dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
+	dh.device.HardwareVersion = deviceInfo.HardwareVersion
+	dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
+
+	if deviceInfo.DeviceId == "" {
+		log.Warnw("no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
+		host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
+		genmac, err := generateMacFromHost(host)
+		if err != nil {
+			return nil, NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err).Log()
+		}
+		log.Debugw("using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
+		dh.device.MacAddress = genmac
+	} else {
+		dh.device.MacAddress = deviceInfo.DeviceId
+	}
+
+	// Synchronous call to update device - this method is run in its own go routine
+	if err := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); err != nil {
+		return nil, NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
+	}
+
+	return deviceInfo, nil
+}
+
+func startCollector(dh *DeviceHandler) {
+	// Initial delay for OLT initialization
+	time.Sleep(1 * time.Minute)
+	log.Debugf("Starting-Collector")
+	context := make(map[string]string)
+	for {
+		select {
+		case <-dh.stopCollector:
+			log.Debugw("Stopping-Collector-for-OLT", log.Fields{"deviceID:": dh.deviceID})
+			return
+		default:
+			freq := dh.metrics.ToPmConfigs().DefaultFreq
+			time.Sleep(time.Duration(freq) * time.Second)
+			context["oltid"] = dh.deviceID
+			context["devicetype"] = dh.deviceType
+			// NNI Stats
+			cmnni := dh.portStats.collectNNIMetrics(uint32(0))
+			log.Debugf("Collect-NNI-Metrics %v", cmnni)
+			go dh.portStats.publishMetrics("NNIStats", cmnni, uint32(0), context, dh.deviceID)
+			log.Debugf("Publish-NNI-Metrics")
+			// PON Stats
+			NumPonPORTS := dh.resourceMgr.DevInfo.GetPonPorts()
+			for i := uint32(0); i < NumPonPORTS; i++ {
+				if val, ok := dh.activePorts.Load(i); ok && val == true {
+					cmpon := dh.portStats.collectPONMetrics(i)
+					log.Debugf("Collect-PON-Metrics %v", cmpon)
+
+					go dh.portStats.publishMetrics("PONStats", cmpon, i, context, dh.deviceID)
+					log.Debugf("Publish-PON-Metrics")
+				}
+			}
+		}
+	}
+}
+
+//AdoptDevice adopts the OLT device
+func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
+	dh.transitionMap = NewTransitionMap(dh)
+	log.Infow("Adopt_device", log.Fields{"deviceID": device.Id, "Address": device.GetHostAndPort()})
+	dh.transitionMap.Handle(ctx, DeviceInit)
+
+	// Now, set the initial PM configuration for that device
+	if err := dh.coreProxy.DevicePMConfigUpdate(nil, dh.metrics.ToPmConfigs()); err != nil {
+		NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
+	}
+
+	go startCollector(dh)
+	go startHeartbeatCheck(dh)
+}
+
+//GetOfpDeviceInfo Gets the Ofp information of the given device
+func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
+	return &ic.SwitchCapability{
+		Desc: &of.OfpDesc{
+			MfrDesc:   "VOLTHA Project",
+			HwDesc:    "open_pon",
+			SwDesc:    "open_pon",
+			SerialNum: dh.device.SerialNumber,
+		},
+		SwitchFeatures: &of.OfpSwitchFeatures{
+			NBuffers: 256,
+			NTables:  2,
+			Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
+				of.OfpCapabilities_OFPC_TABLE_STATS |
+				of.OfpCapabilities_OFPC_PORT_STATS |
+				of.OfpCapabilities_OFPC_GROUP_STATS),
+		},
+	}, nil
+}
+
+//GetOfpPortInfo Get Ofp port information
+func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
+	capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
+	return &ic.PortCapability{
+		Port: &voltha.LogicalPort{
+			OfpPort: &of.OfpPort{
+				HwAddr:     macAddressToUint32Array(dh.device.MacAddress),
+				Config:     0,
+				State:      uint32(of.OfpPortState_OFPPS_LIVE),
+				Curr:       capacity,
+				Advertised: capacity,
+				Peer:       capacity,
+				CurrSpeed:  uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+				MaxSpeed:   uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+			},
+			DeviceId:     dh.device.Id,
+			DevicePortNo: uint32(portNo),
+		},
+	}, nil
+}
+
+func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) error {
+	log.Debugw("omci indication", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
+	var deviceType string
+	var deviceID string
+	var proxyDeviceID string
+
+	onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
+
+	if onuInCache, ok := dh.onus.Load(onuKey); !ok {
+
+		log.Debugw("omci indication for a device not in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
+		ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
+		kwargs := make(map[string]interface{})
+		kwargs["onu_id"] = omciInd.OnuId
+		kwargs["parent_port_no"] = ponPort
+
+		onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
+		if err != nil {
+			return NewErrNotFound("onu", log.Fields{
+				"interface-id": omciInd.IntfId,
+				"onu-id":       omciInd.OnuId}, err).Log()
+		}
+		deviceType = onuDevice.Type
+		deviceID = onuDevice.Id
+		proxyDeviceID = onuDevice.ProxyAddress.DeviceId
+		//if not exist in cache, then add to cache.
+		dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID))
+	} else {
+		//found in cache
+		log.Debugw("omci indication for a device in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
+		deviceType = onuInCache.(*OnuDevice).deviceType
+		deviceID = onuInCache.(*OnuDevice).deviceID
+		proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
+	}
+
+	omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
+	if err := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
+		ic.InterAdapterMessageType_OMCI_REQUEST, dh.deviceType, deviceType,
+		deviceID, proxyDeviceID, ""); err != nil {
+		return NewErrCommunication("omci-request", log.Fields{
+			"source":          dh.deviceType,
+			"destination":     deviceType,
+			"onu-id":          deviceID,
+			"proxy-device-id": proxyDeviceID}, err).Log()
+	}
+	return nil
+}
+
+//ProcessInterAdapterMessage sends the proxied messages to the target device
+// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
+// is meant, and then send the unmarshalled omci message to this onu
+func (dh *DeviceHandler) ProcessInterAdapterMessage(msg *ic.InterAdapterMessage) error {
+	log.Debugw("Process_inter_adapter_message", log.Fields{"msgID": msg.Header.Id})
+	if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
+		msgID := msg.Header.Id
+		fromTopic := msg.Header.FromTopic
+		toTopic := msg.Header.ToTopic
+		toDeviceID := msg.Header.ToDeviceId
+		proxyDeviceID := msg.Header.ProxyDeviceId
+
+		log.Debugw("omci request message header", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
+
+		msgBody := msg.GetBody()
+
+		omciMsg := &ic.InterAdapterOmciMessage{}
+		if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
+			log.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{"error": err})
+			return err
+		}
+
+		if omciMsg.GetProxyAddress() == nil {
+			onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
+			if err != nil {
+				return NewErrNotFound("onu", log.Fields{
+					"device-id":     dh.device.Id,
+					"onu-device-id": toDeviceID}, err).Log()
+			}
+			log.Debugw("device retrieved from core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
+			if err := dh.sendProxiedMessage(onuDevice, omciMsg); err != nil {
+				return NewErrCommunication("send-failed", log.Fields{
+					"device-id":     dh.device.Id,
+					"onu-device-id": toDeviceID}, err).Log()
+			}
+		} else {
+			log.Debugw("Proxy Address found in omci message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
+			if err := dh.sendProxiedMessage(nil, omciMsg); err != nil {
+				return NewErrCommunication("send-failed", log.Fields{
+					"device-id":     dh.device.Id,
+					"onu-device-id": toDeviceID}, err).Log()
+			}
+		}
+
+	} else {
+		return NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil).Log()
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) sendProxiedMessage(onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
+	var intfID uint32
+	var onuID uint32
+	var connectStatus common.ConnectStatus_Types
+	if onuDevice != nil {
+		intfID = onuDevice.ProxyAddress.GetChannelId()
+		onuID = onuDevice.ProxyAddress.GetOnuId()
+		connectStatus = onuDevice.ConnectStatus
+	} else {
+		intfID = omciMsg.GetProxyAddress().GetChannelId()
+		onuID = omciMsg.GetProxyAddress().GetOnuId()
+		connectStatus = omciMsg.GetConnectStatus()
+	}
+	if connectStatus != voltha.ConnectStatus_REACHABLE {
+		log.Debugw("ONU is not reachable, cannot send OMCI", log.Fields{"intfID": intfID, "onuID": onuID})
+
+		return NewErrCommunication("unreachable", log.Fields{
+			"interface-id": intfID,
+			"onu-id":       onuID}, nil).Log()
+	}
+
+	// TODO: Once we are sure openonu/openomci is sending only binary in omciMsg.Message, we can remove this check
+	isHexString := false
+	_, decodeerr := hex.DecodeString(string(omciMsg.Message))
+	if decodeerr == nil {
+		isHexString = true
+	}
+
+	// TODO: OpenOLT Agent expects a hex string for OMCI packets rather than binary.  Fix this in the agent and then we can pass binary Pkt: omciMsg.Message.
+	var omciMessage *oop.OmciMsg
+	if isHexString {
+		omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: omciMsg.Message}
+	} else {
+		hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
+		hex.Encode(hexPkt, omciMsg.Message)
+		omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
+	}
+
+	_, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
+	if err != nil {
+		return NewErrCommunication("omci-send-failed", log.Fields{
+			"interface-id": intfID,
+			"onu-id":       onuID,
+			"message":      omciMessage}, err).Log()
+	}
+	log.Debugw("Sent Omci message", log.Fields{"intfID": intfID, "onuID": onuID, "omciMsg": hex.EncodeToString(omciMsg.Message)})
+	return nil
+}
+
+func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
+	log.Debugw("activate-onu", log.Fields{"intfID": intfID, "onuID": onuID, "serialNum": serialNum, "serialNumber": serialNumber})
+	dh.flowMgr.UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber)
+	// TODO: need resource manager
+	var pir uint32 = 1000000
+	Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
+	if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
+		st, _ := status.FromError(err)
+		if st.Code() == codes.AlreadyExists {
+			log.Debug("ONU activation is in progress", log.Fields{"SerialNumber": serialNumber})
+		} else {
+			return NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu}, err).Log()
+		}
+	} else {
+		log.Infow("activated-onu", log.Fields{"SerialNumber": serialNumber})
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
+
+	channelID := onuDiscInd.GetIntfId()
+	parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
+
+	log.Infow("new-discovery-indication", log.Fields{"sn": sn})
+
+	kwargs := make(map[string]interface{})
+	if sn != "" {
+		kwargs["serial_number"] = sn
+	} else {
+		return NewErrInvalidValue(log.Fields{"serial-number": sn}, nil).Log()
+	}
+
+	if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
+		log.Warnw("onu-sn-is-already-being-processed", log.Fields{"sn": sn})
+		return nil
+	}
+
+	var onuID uint32
+
+	// check the ONU is already know to the OLT
+	// NOTE the second time the ONU is discovered this should return a device
+	onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
+
+	if err != nil {
+		log.Warnw("core-proxy-get-child-device-failed", log.Fields{"parentDevice": dh.device.Id, "err": err, "sn": sn})
+		if e, ok := status.FromError(err); ok {
+			log.Warnw("core-proxy-get-child-device-failed-with-code", log.Fields{"errCode": e.Code(), "sn": sn})
+			switch e.Code() {
+			case codes.Internal:
+				// this probably means NOT FOUND, so just create a new device
+				onuDevice = nil
+			case codes.DeadlineExceeded:
+				// if the call times out, cleanup and exit
+				dh.discOnus.Delete(sn)
+				return NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err).Log()
+			}
+		}
+	}
+
+	if onuDevice == nil {
+		// NOTE this should happen a single time, and only if GetChildDevice returns NotFound
+		log.Infow("creating-new-onu", log.Fields{"sn": sn})
+		// we need to create a new ChildDevice
+		ponintfid := onuDiscInd.GetIntfId()
+		dh.lockDevice.Lock()
+		onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
+		dh.lockDevice.Unlock()
+
+		log.Infow("creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
+
+		if err != nil {
+			// if we can't create an ID in resource manager,
+			// cleanup and exit
+			dh.discOnus.Delete(sn)
+			return NewErrAdapter("resource-manage-get-onu-id-failed", log.Fields{
+				"pon-interface-id": ponintfid,
+				"serial-number":    sn}, err).Log()
+		}
+
+		if onuDevice, err = dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
+			"", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
+			dh.discOnus.Delete(sn)
+			dh.resourceMgr.FreeonuID(ctx, ponintfid, []uint32{onuID}) // NOTE I'm not sure this method is actually cleaning up the right thing
+			return NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
+				"pon-interface-id": ponintfid,
+				"serial-number":    sn}, err).Log()
+		}
+
+		log.Infow("onu-child-device-added", log.Fields{"onuDevice": onuDevice, "sn": sn})
+	}
+
+	// we can now use the existing ONU Id
+	onuID = onuDevice.ProxyAddress.OnuId
+
+	//Insert the ONU into cache to use in OnuIndication.
+	//TODO: Do we need to remove this from the cache on ONU change, or wait for overwritten on next discovery.
+	log.Debugw("onu-discovery-indication-key-create", log.Fields{"onuID": onuID,
+		"intfId": onuDiscInd.GetIntfId(), "sn": sn})
+	onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
+
+	onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId)
+	dh.onus.Store(onuKey, onuDev)
+	log.Debugw("new-onu-device-discovered", log.Fields{"onu": onuDev, "sn": sn})
+
+	if err = dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
+		return NewErrAdapter("failed-to-update-device-state", log.Fields{
+			"device-id":     onuDevice.Id,
+			"serial-number": sn}, err).Log()
+	}
+	log.Infow("onu-discovered-reachable", log.Fields{"deviceId": onuDevice.Id, "sn": sn})
+	if err = dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
+		return NewErrAdapter("onu-activation-failed", log.Fields{
+			"device-id":     onuDevice.Id,
+			"serial-number": sn}, err).Log()
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) onuIndication(onuInd *oop.OnuIndication) error {
+	serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
+
+	kwargs := make(map[string]interface{})
+	ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
+	var onuDevice *voltha.Device
+	var err error
+	foundInCache := false
+	log.Debugw("ONU indication key create", log.Fields{"onuId": onuInd.OnuId,
+		"intfId": onuInd.GetIntfId()})
+	onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
+
+	errFields := log.Fields{"device-id": dh.device.Id}
+
+	if onuInCache, ok := dh.onus.Load(onuKey); ok {
+
+		//If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
+		foundInCache = true
+		errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
+		onuDevice, err = dh.coreProxy.GetDevice(nil, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
+	} else {
+		//If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
+		if serialNumber != "" {
+			kwargs["serial_number"] = serialNumber
+			errFields["serial-number"] = serialNumber
+		} else {
+			kwargs["onu_id"] = onuInd.OnuId
+			kwargs["parent_port_no"] = ponPort
+			errFields["onu-id"] = onuInd.OnuId
+			errFields["parent-port-no"] = ponPort
+		}
+		onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
+	}
+
+	if err != nil || onuDevice == nil {
+		return NewErrNotFound("onu-device", errFields, err).Log()
+	}
+
+	if onuDevice.ParentPortNo != ponPort {
+		log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{
+			"previousIntfId": onuDevice.ParentPortNo,
+			"currentIntfId":  ponPort})
+	}
+
+	if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
+		log.Warnw("ONU-id-mismatch, can happen if both voltha and the olt rebooted", log.Fields{
+			"expected_onu_id": onuDevice.ProxyAddress.OnuId,
+			"received_onu_id": onuInd.OnuId})
+	}
+	if !foundInCache {
+		onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
+
+		dh.onus.Store(onuKey, NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId))
+
+	}
+	if err := dh.updateOnuStates(onuDevice, onuInd); err != nil {
+		return NewErrCommunication("state-update-failed", errFields, err).Log()
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) updateOnuStates(onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
+	ctx := context.TODO()
+	log.Debugw("onu-indication-for-state", log.Fields{"onuIndication": onuInd, "DeviceId": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
+	if onuInd.AdminState == "down" {
+		// Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
+		if onuInd.OperState != "down" {
+			log.Warnw("ONU-admin-state-down", log.Fields{"operState": onuInd.OperState})
+			onuInd.OperState = "down"
+		}
+	}
+
+	switch onuInd.OperState {
+	case "down":
+		log.Debugw("sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "DeviceId": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
+		// TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
+		err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
+			"openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
+		if err != nil {
+			return NewErrCommunication("inter-adapter-send-failed", log.Fields{
+				"onu-indicator": onuInd,
+				"source":        "openolt",
+				"device-type":   onuDevice.Type,
+				"device-id":     onuDevice.Id}, err).Log()
+		}
+	case "up":
+		log.Debugw("sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "DeviceId": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
+		// TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
+		err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
+			"openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
+		if err != nil {
+			return NewErrCommunication("inter-adapter-send-failed", log.Fields{
+				"onu-indicator": onuInd,
+				"source":        "openolt",
+				"device-type":   onuDevice.Type,
+				"device-id":     onuDevice.Id}, err).Log()
+		}
+	default:
+		return NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil).Log()
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
+	if serialNum != nil {
+		return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
+	}
+	return ""
+}
+func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
+	decodedStr, err := hex.DecodeString(serialNum[4:])
+	if err != nil {
+		return nil, err
+	}
+	return &oop.SerialNumber{
+		VendorId:       []byte(serialNum[:4]),
+		VendorSpecific: []byte(decodedStr),
+	}, nil
+}
+
+func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
+	tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
+		fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
+		fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
+		fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
+		fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
+		fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
+		fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
+		fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
+	return tmp
+}
+
+//UpdateFlowsBulk upates the bulk flow
+func (dh *DeviceHandler) UpdateFlowsBulk() error {
+	return ErrNotImplemented
+}
+
+//GetChildDevice returns the child device for given parent port and onu id
+func (dh *DeviceHandler) GetChildDevice(parentPort, onuID uint32) (*voltha.Device, error) {
+	log.Debugw("GetChildDevice", log.Fields{"pon port": parentPort, "onuID": onuID})
+	kwargs := make(map[string]interface{})
+	kwargs["onu_id"] = onuID
+	kwargs["parent_port_no"] = parentPort
+	onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
+	if err != nil {
+		return nil, NewErrNotFound("onu", log.Fields{
+			"interface-id": parentPort,
+			"onu-id":       onuID}, err).Log()
+	}
+	log.Debugw("Successfully received child device from core", log.Fields{"child_device": *onuDevice})
+	return onuDevice, nil
+}
+
+// SendPacketInToCore sends packet-in to core
+// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
+// The adapter handling the device creates a device specific topic
+func (dh *DeviceHandler) SendPacketInToCore(logicalPort uint32, packetPayload []byte) error {
+	log.Debugw("send-packet-in-to-core", log.Fields{
+		"port":   logicalPort,
+		"packet": hex.EncodeToString(packetPayload),
+	})
+	if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
+		return NewErrCommunication("packet-send-failed", log.Fields{
+			"source":       "adapter",
+			"destination":  "core",
+			"device-id":    dh.device.Id,
+			"logical-port": logicalPort,
+			"packet":       hex.EncodeToString(packetPayload)}, err).Log()
+	}
+	log.Debugw("Sent packet-in to core successfully", log.Fields{
+		"packet": hex.EncodeToString(packetPayload),
+	})
+	return nil
+}
+
+// AddUniPortToOnu adds the uni port to the onu device
+func (dh *DeviceHandler) AddUniPortToOnu(intfID, onuID, uniPort uint32) {
+	onuKey := dh.formOnuKey(intfID, onuID)
+
+	if onuDevice, ok := dh.onus.Load(onuKey); ok {
+		// add it to the uniPort map for the onu device
+		if _, ok = onuDevice.(*OnuDevice).uniPorts[uniPort]; !ok {
+			onuDevice.(*OnuDevice).uniPorts[uniPort] = struct{}{}
+			log.Debugw("adding-uni-port", log.Fields{"port": uniPort, "intfID": intfID, "onuId": onuID})
+		}
+	}
+}
+
+//UpdateFlowsIncrementally updates the device flow
+func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
+	log.Debugw("Received-incremental-flowupdate-in-device-handler", log.Fields{"deviceID": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
+	if flows != nil {
+		for _, flow := range flows.ToRemove.Items {
+			log.Debug("Removing flow", log.Fields{"deviceId": device.Id, "flowToRemove": flow})
+			dh.flowMgr.RemoveFlow(ctx, flow)
+		}
+
+		for _, flow := range flows.ToAdd.Items {
+			log.Debug("Adding flow", log.Fields{"deviceId": device.Id, "flowToAdd": flow})
+			dh.flowMgr.AddFlow(ctx, flow, flowMetadata)
+		}
+	}
+	if groups != nil && flows != nil {
+		for _, flow := range flows.ToRemove.Items {
+			log.Debug("Removing flow", log.Fields{"deviceID": device.Id, "flowToRemove": flow})
+			//  dh.flowMgr.RemoveFlow(flow)
+		}
+	}
+
+	if groups != nil {
+		for _, group := range groups.ToAdd.Items {
+			dh.flowMgr.AddGroup(ctx, group)
+		}
+		for _, group := range groups.ToUpdate.Items {
+			dh.flowMgr.ModifyGroup(ctx, group)
+		}
+		if len(groups.ToRemove.Items) != 0 {
+			log.Debug("Group delete operation is not supported for now")
+		}
+	}
+	log.Debug("UpdateFlowsIncrementally done successfully")
+	return nil
+}
+
+//DisableDevice disables the given device
+//It marks the following for the given device:
+//Device-Handler Admin-State : down
+//Device Port-State: UNKNOWN
+//Device Oper-State: UNKNOWN
+func (dh *DeviceHandler) DisableDevice(device *voltha.Device) error {
+	/* On device disable ,admin state update has to be done prior sending request to agent since
+	   the indication thread may processes invalid  indications of ONU and OLT*/
+	dh.lockDevice.Lock()
+	dh.adminState = "down"
+	dh.lockDevice.Unlock()
+	if dh.Client != nil {
+		if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
+			if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
+				dh.lockDevice.Lock()
+				dh.adminState = "up"
+				dh.lockDevice.Unlock()
+				return NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err).Log()
+			}
+		}
+	}
+	log.Debugw("olt-disabled", log.Fields{"deviceID": device.Id})
+	/* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
+	UNREACHABLE state which needs to be configured again*/
+
+	dh.discOnus = sync.Map{}
+	dh.onus = sync.Map{}
+
+	go dh.notifyChildDevices("unreachable")
+	cloned := proto.Clone(device).(*voltha.Device)
+	// Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
+	for _, port := range cloned.Ports {
+		if port.GetType() == voltha.Port_PON_OLT {
+			if err := dh.coreProxy.PortStateUpdate(context.TODO(), cloned.Id,
+				voltha.Port_PON_OLT, port.GetPortNo(), voltha.OperStatus_UNKNOWN); err != nil {
+				return err
+			}
+		}
+	}
+
+	log.Debugw("disable-device-end", log.Fields{"deviceID": device.Id})
+	return nil
+}
+
+func (dh *DeviceHandler) notifyChildDevices(state string) {
+
+	// Update onu state as unreachable in onu adapter
+	onuInd := oop.OnuIndication{}
+	onuInd.OperState = state
+	//get the child device for the parent device
+	onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
+	if err != nil {
+		log.Errorw("failed-to-get-child-devices-information", log.Fields{"deviceID": dh.device.Id, "error": err})
+	}
+	if onuDevices != nil {
+		for _, onuDevice := range onuDevices.Items {
+			err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
+				"openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
+			if err != nil {
+				log.Errorw("failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
+					"From Adapter": "openolt", "DeviceType": onuDevice.Type, "DeviceID": onuDevice.Id})
+			}
+
+		}
+	}
+
+}
+
+//ReenableDevice re-enables the olt device after disable
+//It marks the following for the given device:
+//Device-Handler Admin-State : up
+//Device Port-State: ACTIVE
+//Device Oper-State: ACTIVE
+func (dh *DeviceHandler) ReenableDevice(device *voltha.Device) error {
+	dh.lockDevice.Lock()
+	dh.adminState = "up"
+	dh.lockDevice.Unlock()
+
+	if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
+		if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
+			dh.lockDevice.Lock()
+			dh.adminState = "down"
+			dh.lockDevice.Unlock()
+			return NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
+		}
+	}
+	log.Debug("olt-reenabled")
+
+	cloned := proto.Clone(device).(*voltha.Device)
+	// Update the all ports state on that device to enable
+
+	if err := dh.disableAdminDownPorts(device); err != nil {
+		return NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err).Log()
+	}
+	//Update the device oper status as ACTIVE
+	cloned.OperStatus = voltha.OperStatus_ACTIVE
+	dh.device = cloned
+
+	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
+		return NewErrAdapter("state-update-failed", log.Fields{
+			"device-id":      device.Id,
+			"connect-status": cloned.ConnectStatus,
+			"oper-status":    cloned.OperStatus}, err).Log()
+	}
+
+	log.Debugw("ReEnableDevice-end", log.Fields{"deviceID": device.Id})
+
+	return nil
+}
+
+func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
+	var uniID uint32
+	var err error
+	for _, port := range onu.UniPorts {
+		uniID = UniIDFromPortNum(uint32(port))
+		log.Debugw("clearing-resource-data-for-uni-port", log.Fields{"port": port, "uniID": uniID})
+		/* Delete tech-profile instance from the KV store */
+		if err = dh.flowMgr.DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID, onu.SerialNumber); err != nil {
+			log.Debugw("Failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
+		}
+		log.Debugw("Deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
+		flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID))
+		for _, flowID := range flowIDs {
+			dh.resourceMgr.FreeFlowID(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID), flowID)
+		}
+		tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
+		for _, tpID := range tpIDList {
+			if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
+				log.Debugw("Failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
+			}
+			log.Debugw("Removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
+			if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
+				log.Debugw("Failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
+			}
+			log.Debugw("Removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
+		}
+		dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
+		if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
+			log.Debugw("Failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
+		}
+		log.Debugw("Removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
+		if err = dh.resourceMgr.DelGemPortPktIn(ctx, onu.IntfID, onu.OnuID, uint32(port)); err != nil {
+			log.Debugw("Failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
+		}
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
+	nniUniID := -1
+	nniOnuID := -1
+
+	if dh.resourceMgr == nil {
+		return fmt.Errorf("no resource manager for deviceID %s", dh.deviceID)
+	}
+	//Free the flow-ids for the NNI port
+	nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
+	if err != nil {
+		return NewErrPersistence("get", "nni", 0, nil, err).Log()
+	}
+	log.Debugw("NNI are ", log.Fields{"nni": nni})
+	for _, nniIntfID := range nni {
+		flowIDs := dh.resourceMgr.GetCurrentFlowIDsForOnu(ctx, uint32(nniIntfID), int32(nniOnuID), int32(nniUniID))
+		log.Debugw("Current flow ids for nni", log.Fields{"flow-ids": flowIDs})
+		for _, flowID := range flowIDs {
+			dh.resourceMgr.FreeFlowID(ctx, uint32(nniIntfID), -1, -1, uint32(flowID))
+		}
+		dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
+	}
+	if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
+		return NewErrPersistence("clear", "nni", 0, nil, err).Log()
+	}
+	return nil
+}
+
+// DeleteDevice deletes the device instance from openolt handler array.  Also clears allocated resource manager resources.  Also reboots the OLT hardware!
+func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
+	log.Debug("Function entry delete device")
+	dh.lockDevice.Lock()
+	if dh.adminState == "deleted" {
+		dh.lockDevice.Unlock()
+		return nil
+	}
+	dh.adminState = "deleted"
+	dh.lockDevice.Unlock()
+	/* Clear the KV store data associated with the all the UNI ports
+	   This clears up flow data and also resource map data for various
+	   other pon resources like alloc_id and gemport_id
+	*/
+	if dh.resourceMgr != nil {
+		noOfPonPorts := dh.resourceMgr.DevInfo.GetPonPorts()
+		var ponPort uint32
+		for ponPort = 0; ponPort < noOfPonPorts; ponPort++ {
+			var onuGemData []rsrcMgr.OnuGemInfo
+			err := dh.resourceMgr.ResourceMgrs[ponPort].GetOnuGemInfo(ctx, ponPort, &onuGemData)
+			if err != nil {
+				return NewErrNotFound("onu", log.Fields{
+					"device-id": dh.device.Id,
+					"pon-port":  ponPort}, err).Log()
+			}
+			for _, onu := range onuGemData {
+				onuID := make([]uint32, 1)
+				log.Debugw("onu data ", log.Fields{"onu": onu})
+				if err = dh.clearUNIData(ctx, &onu); err != nil {
+					log.Errorw("Failed to clear data for onu", log.Fields{"onu-device": onu})
+				}
+				// Clear flowids for gem cache.
+				for _, gem := range onu.GemPorts {
+					dh.resourceMgr.DeleteFlowIDsForGem(ctx, ponPort, gem)
+				}
+				onuID[0] = onu.OnuID
+				dh.resourceMgr.FreeonuID(ctx, ponPort, onuID)
+			}
+			dh.resourceMgr.DeleteIntfIDGempMapPath(ctx, ponPort)
+			onuGemData = nil
+			err = dh.resourceMgr.DelOnuGemInfoForIntf(ctx, ponPort)
+			if err != nil {
+				log.Errorw("Failed to update onugem info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
+			}
+		}
+		/* Clear the flows from KV store associated with NNI port.
+		   There are mostly trap rules from NNI port (like LLDP)
+		*/
+		if err := dh.clearNNIData(ctx); err != nil {
+			log.Errorw("Failed to clear data for NNI port", log.Fields{"device-id": dh.deviceID})
+		}
+
+		/* Clear the resource pool for each PON port in the background */
+		go dh.resourceMgr.Delete(ctx)
+	}
+
+	/*Delete ONU map for the device*/
+	dh.onus.Range(func(key interface{}, value interface{}) bool {
+		dh.onus.Delete(key)
+		return true
+	})
+
+	log.Debug("Removed-device-from-Resource-manager-KV-store")
+	// Stop the Stats collector
+	dh.stopCollector <- true
+	// stop the heartbeat check routine
+	dh.stopHeartbeatCheck <- true
+	//Reset the state
+	if dh.Client != nil {
+		if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
+			return NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.deviceID}, err).Log()
+		}
+	}
+	cloned := proto.Clone(device).(*voltha.Device)
+	cloned.OperStatus = voltha.OperStatus_UNKNOWN
+	cloned.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
+	if err := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
+		return NewErrAdapter("device-state-update-failed", log.Fields{
+			"device-id":      device.Id,
+			"connect-status": cloned.ConnectStatus,
+			"oper-status":    cloned.OperStatus}, err).Log()
+	}
+	return nil
+}
+
+//RebootDevice reboots the given device
+func (dh *DeviceHandler) RebootDevice(device *voltha.Device) error {
+	if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
+		return NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.deviceID}, err).Log()
+	}
+	log.Debugw("rebooted-device-successfully", log.Fields{"deviceID": device.Id})
+	return nil
+}
+
+func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
+	log.Debugw("Received packet-in", log.Fields{
+		"packet-indication": *packetIn,
+		"packet":            hex.EncodeToString(packetIn.Pkt),
+	})
+	logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(ctx, packetIn)
+	if err != nil {
+		return NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err).Log()
+	}
+	log.Debugw("sending packet-in to core", log.Fields{
+		"logicalPortNum": logicalPortNum,
+		"packet":         hex.EncodeToString(packetIn.Pkt),
+	})
+	if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
+		return NewErrCommunication("send-packet-in", log.Fields{
+			"destination": "core",
+			"source":      dh.deviceType,
+			"packet":      hex.EncodeToString(packetIn.Pkt)}, err).Log()
+	}
+	log.Debugw("Success sending packet-in to core!", log.Fields{
+		"packet": hex.EncodeToString(packetIn.Pkt),
+	})
+	return nil
+}
+
+// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
+func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
+	log.Debugw("incoming-packet-out", log.Fields{
+		"deviceID":       dh.deviceID,
+		"egress_port_no": egressPortNo,
+		"pkt-length":     len(packet.Data),
+		"packet":         hex.EncodeToString(packet.Data),
+	})
+
+	egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
+	if egressPortType == voltha.Port_ETHERNET_UNI {
+		outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
+		innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
+		if outerEthType == 0x8942 || outerEthType == 0x88cc {
+			// Do not packet-out lldp packets on uni port.
+			// ONOS has no clue about uni/nni ports, it just packets out on all
+			// available ports on the Logical Switch. It should not be interested
+			// in the UNI links.
+			log.Debug("dropping-lldp-packet-out-on-uni")
+			return nil
+		}
+		if outerEthType == 0x88a8 || outerEthType == 0x8100 {
+			if innerEthType == 0x8100 {
+				// q-in-q 802.1ad or 802.1q double tagged packet.
+				// slice out the outer tag.
+				packet.Data = append(packet.Data[:12], packet.Data[16:]...)
+				log.Debugw("packet-now-single-tagged", log.Fields{"packetData": hex.EncodeToString(packet.Data)})
+			}
+		}
+		intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
+		onuID := OnuIDFromPortNum(uint32(egressPortNo))
+		uniID := UniIDFromPortNum(uint32(egressPortNo))
+
+		gemPortID, err := dh.flowMgr.GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo))
+		if err != nil {
+			// In this case the openolt agent will receive the gemPortID as 0.
+			// The agent tries to retrieve the gemPortID in this case.
+			// This may not always succeed at the agent and packetOut may fail.
+			log.Errorw("failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
+				"packet": hex.EncodeToString(packet.Data),
+			})
+		}
+
+		onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
+
+		log.Debugw("sending-packet-to-onu", log.Fields{
+			"egress_port_no": egressPortNo,
+			"IntfId":         intfID,
+			"onuID":          onuID,
+			"uniID":          uniID,
+			"gemPortID":      gemPortID,
+			"packet":         hex.EncodeToString(packet.Data),
+		})
+
+		if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
+			return NewErrCommunication("packet-out-send", log.Fields{
+				"source":             "adapter",
+				"destination":        "onu",
+				"egress-port-number": egressPortNo,
+				"interface-id":       intfID,
+				"oni-id":             onuID,
+				"uni-id":             uniID,
+				"gem-port-id":        gemPortID,
+				"packet":             hex.EncodeToString(packet.Data)}, err).Log()
+		}
+	} else if egressPortType == voltha.Port_ETHERNET_NNI {
+		nniIntfID, err := IntfIDFromNniPortNum(uint32(egressPortNo))
+		if err != nil {
+			return NewErrInvalidValue(log.Fields{"egress-nni-port": egressPortNo}, err).Log()
+		}
+		uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
+
+		log.Debugw("sending-packet-to-nni", log.Fields{
+			"uplink_pkt": uplinkPkt,
+			"packet":     hex.EncodeToString(packet.Data),
+		})
+
+		if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
+			return NewErrCommunication("packet-out-to-nni", log.Fields{"packet": hex.EncodeToString(packet.Data)}, err).Log()
+		}
+	} else {
+		log.Warnw("Packet-out-to-this-interface-type-not-implemented", log.Fields{
+			"egress_port_no": egressPortNo,
+			"egressPortType": egressPortType,
+			"packet":         hex.EncodeToString(packet.Data),
+		})
+	}
+	return nil
+}
+
+func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
+	return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
+}
+
+func startHeartbeatCheck(dh *DeviceHandler) {
+	// start the heartbeat check towards the OLT.
+	var timerCheck *time.Timer
+
+	for {
+		heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
+		select {
+		case <-heartbeatTimer.C:
+			ctx, cancel := context.WithTimeout(context.Background(), dh.openOLT.GrpcTimeoutInterval)
+			if heartBeat, err := dh.Client.HeartbeatCheck(ctx, new(oop.Empty)); err != nil {
+				log.Error("Hearbeat failed")
+				if timerCheck == nil {
+					// start a after func, when expired will update the state to the core
+					timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, dh.updateStateUnreachable)
+				}
+			} else {
+				if timerCheck != nil {
+					if timerCheck.Stop() {
+						log.Debug("We got hearbeat within the timeout")
+					} else {
+
+						log.Debug("We got hearbeat after the timeout expired, changing the states")
+						go dh.notifyChildDevices("up")
+						if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
+							voltha.OperStatus_ACTIVE); err != nil {
+							log.Errorw("Failed to update device state", log.Fields{"deviceID": dh.device.Id, "error": err})
+						}
+					}
+					timerCheck = nil
+				}
+				log.Debugw("Hearbeat", log.Fields{"signature": heartBeat})
+			}
+			cancel()
+		case <-dh.stopHeartbeatCheck:
+			log.Debug("Stopping heart beat check")
+			return
+		}
+	}
+}
+
+func (dh *DeviceHandler) updateStateUnreachable() {
+
+	go dh.notifyChildDevices("unreachable")
+	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
+		NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
+	}
+}
+
+// EnablePort to enable Pon interface
+func (dh *DeviceHandler) EnablePort(port *voltha.Port) error {
+	log.Debugw("enable-port", log.Fields{"Device": dh.device, "port": port})
+	return dh.modifyPhyPort(port, true)
+}
+
+// DisablePort to disable pon interface
+func (dh *DeviceHandler) DisablePort(port *voltha.Port) error {
+	log.Debugw("disable-port", log.Fields{"Device": dh.device, "port": port})
+	return dh.modifyPhyPort(port, false)
+}
+
+//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
+func (dh *DeviceHandler) modifyPhyPort(port *voltha.Port, enablePort bool) error {
+	ctx := context.Background()
+	log.Infow("modifyPhyPort", log.Fields{"port": port, "Enable": enablePort})
+	if port.GetType() == voltha.Port_ETHERNET_NNI {
+		// Bug is opened for VOL-2505 to support NNI disable feature.
+		log.Infow("voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
+			log.Fields{"Device": dh.device, "port": port})
+		return NewErrAdapter("illegal-port-request", log.Fields{
+			"port-type":    port.GetType,
+			"enable-state": enablePort}, nil).Log()
+	}
+	// fetch interfaceid from PortNo
+	ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
+	ponIntf := &oop.Interface{IntfId: ponID}
+	var operStatus voltha.OperStatus_Types
+	if enablePort {
+		operStatus = voltha.OperStatus_ACTIVE
+		out, err := dh.Client.EnablePonIf(ctx, ponIntf)
+
+		if err != nil {
+			return NewErrAdapter("pon-port-enable-failed", log.Fields{
+				"device-id": dh.device.Id,
+				"port":      port}, err).Log()
+		}
+		// updating interface local cache for collecting stats
+		dh.activePorts.Store(ponID, true)
+		log.Infow("enabled-pon-port", log.Fields{"out": out, "DeviceID": dh.device, "Port": port})
+	} else {
+		operStatus = voltha.OperStatus_UNKNOWN
+		out, err := dh.Client.DisablePonIf(ctx, ponIntf)
+		if err != nil {
+			return NewErrAdapter("pon-port-disable-failed", log.Fields{
+				"device-id": dh.device.Id,
+				"port":      port}, err).Log()
+		}
+		// updating interface local cache for collecting stats
+		dh.activePorts.Store(ponID, false)
+		log.Infow("disabled-pon-port", log.Fields{"out": out, "DeviceID": dh.device, "Port": port})
+	}
+	if err := dh.coreProxy.PortStateUpdate(ctx, dh.deviceID, voltha.Port_PON_OLT, port.PortNo, operStatus); err != nil {
+		return NewErrAdapter("port-state-update-failed", log.Fields{
+			"device-id": dh.deviceID,
+			"port":      port.PortNo}, err).Log()
+	}
+	return nil
+}
+
+//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
+func (dh *DeviceHandler) disableAdminDownPorts(device *voltha.Device) error {
+	cloned := proto.Clone(device).(*voltha.Device)
+	// Disable the port and update the oper_port_status to core
+	// if the Admin state of the port is disabled on reboot and re-enable device.
+	for _, port := range cloned.Ports {
+		if port.AdminState == common.AdminState_DISABLED {
+			if err := dh.DisablePort(port); err != nil {
+				return NewErrAdapter("port-disable-failed", log.Fields{
+					"device-id": dh.deviceID,
+					"port":      port}, err).Log()
+			}
+		}
+	}
+	return nil
+}
+
+//populateActivePorts to populate activePorts map
+func (dh *DeviceHandler) populateActivePorts(device *voltha.Device) {
+	log.Info("populateActiveports", log.Fields{"Device": device})
+	for _, port := range device.Ports {
+		if port.Type == voltha.Port_ETHERNET_NNI {
+			if port.OperStatus == voltha.OperStatus_ACTIVE {
+				dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
+			} else {
+				dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
+			}
+		}
+		if port.Type == voltha.Port_PON_OLT {
+			if port.OperStatus == voltha.OperStatus_ACTIVE {
+				dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
+			} else {
+				dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
+			}
+		}
+	}
+}
+
+// ChildDeviceLost deletes ONU and clears pon resources related to it.
+func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32) error {
+	log.Debugw("child-device-lost", log.Fields{"pdeviceID": dh.device.Id})
+	IntfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
+	onuKey := dh.formOnuKey(IntfID, onuID)
+	onuDevice, ok := dh.onus.Load(onuKey)
+	if !ok {
+		return NewErrAdapter("failed-to-load-onu-details",
+			log.Fields{
+				"device-id":    dh.deviceID,
+				"onu-id":       onuID,
+				"interface-id": IntfID}, nil).Log()
+	}
+	var sn *oop.SerialNumber
+	var err error
+	if sn, err = dh.deStringifySerialNumber(onuDevice.(*OnuDevice).serialNumber); err != nil {
+		return NewErrAdapter("failed-to-destringify-serial-number",
+			log.Fields{
+				"devicer-id":    dh.deviceID,
+				"serial-number": onuDevice.(*OnuDevice).serialNumber}, err).Log()
+	}
+	onu := &oop.Onu{IntfId: IntfID, OnuId: onuID, SerialNumber: sn}
+	if _, err := dh.Client.DeleteOnu(context.Background(), onu); err != nil {
+		return NewErrAdapter("failed-to-delete-onu", log.Fields{
+			"device-id": dh.deviceID,
+			"onu-id":    onuID}, err).Log()
+	}
+	//clear PON resources associated with ONU
+	var onuGemData []rsrcMgr.OnuGemInfo
+	if err := dh.resourceMgr.ResourceMgrs[IntfID].GetOnuGemInfo(ctx, IntfID, &onuGemData); err != nil {
+		log.Errorw("Failed-to-get-onu-info-for-pon-port ", log.Fields{
+			"device-id":    dh.deviceID,
+			"interface-id": IntfID,
+			"error":        err})
+	}
+
+	for i, onu := range onuGemData {
+		if onu.OnuID == onuID && onu.SerialNumber == onuDevice.(*OnuDevice).serialNumber {
+			log.Debugw("onu-data ", log.Fields{"onu": onu})
+			if err := dh.clearUNIData(ctx, &onu); err != nil {
+				log.Errorw("Failed-to-clear-uni-data-for-onu", log.Fields{
+					"device-id":  dh.deviceID,
+					"onu-device": onu,
+					"error":      err})
+			}
+			// Clear flowids for gem cache.
+			for _, gem := range onu.GemPorts {
+				dh.resourceMgr.DeleteFlowIDsForGem(ctx, IntfID, gem)
+			}
+			onuGemData = append(onuGemData[:i], onuGemData[i+1:]...)
+			dh.resourceMgr.UpdateOnuGemInfo(ctx, IntfID, onuGemData)
+
+			dh.resourceMgr.FreeonuID(ctx, IntfID, []uint32{onu.OnuID})
+			break
+		}
+	}
+	dh.onus.Delete(onuKey)
+	dh.discOnus.Delete(onuDevice.(*OnuDevice).serialNumber)
+	return nil
+}
diff --git a/internal/pkg/core/device_handler_test.go b/internal/pkg/core/device_handler_test.go
new file mode 100644
index 0000000..1d1192e
--- /dev/null
+++ b/internal/pkg/core/device_handler_test.go
@@ -0,0 +1,1171 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"net"
+	"reflect"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/pmmetrics"
+
+	"github.com/golang/protobuf/ptypes"
+	"github.com/golang/protobuf/ptypes/any"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ponrmgr "github.com/opencord/voltha-lib-go/v3/pkg/ponresourcemanager"
+	"github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
+	"github.com/opencord/voltha-openolt-adapter/pkg/mocks"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	of "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	oop "github.com/opencord/voltha-protos/v3/go/openolt"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+func init() {
+	_, _ = log.AddPackage(log.JSON, log.DebugLevel, nil)
+}
+
+func newMockCoreProxy() *mocks.MockCoreProxy {
+	mcp := mocks.MockCoreProxy{}
+	mcp.Devices = make(map[string]*voltha.Device)
+	var pm []*voltha.PmConfig
+	mcp.Devices["olt"] = &voltha.Device{
+
+		Id:           "olt",
+		Root:         true,
+		ParentId:     "logical_device",
+		ParentPortNo: 1,
+
+		Ports: []*voltha.Port{
+			{PortNo: 1, Label: "pon"},
+			{PortNo: 2, Label: "nni"},
+		},
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "olt",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+		PmConfigs: &voltha.PmConfigs{
+			DefaultFreq:  10,
+			Id:           "olt",
+			FreqOverride: false,
+			Grouped:      false,
+			Metrics:      pm,
+		},
+	}
+	mcp.Devices["onu1"] = &voltha.Device{
+
+		Id:           "1",
+		Root:         false,
+		ParentId:     "olt",
+		ParentPortNo: 1,
+
+		Ports: []*voltha.Port{
+			{PortNo: 1, Label: "pon"},
+			{PortNo: 2, Label: "uni"},
+		},
+		OperStatus: 4,
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			OnuId:          1,
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+		PmConfigs: &voltha.PmConfigs{
+			DefaultFreq:  10,
+			Id:           "olt",
+			FreqOverride: false,
+			Grouped:      false,
+			Metrics:      pm,
+		},
+	}
+	mcp.Devices["onu2"] = &voltha.Device{
+		Id:         "2",
+		Root:       false,
+		ParentId:   "olt",
+		OperStatus: 2,
+		Ports: []*voltha.Port{
+			{PortNo: 1, Label: "pon"},
+			{PortNo: 2, Label: "uni"},
+		},
+
+		ParentPortNo: 1,
+
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			OnuId:          2,
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+		PmConfigs: &voltha.PmConfigs{
+			DefaultFreq:  10,
+			Id:           "olt",
+			FreqOverride: false,
+			Grouped:      false,
+			Metrics:      pm,
+		},
+	}
+	return &mcp
+}
+func newMockDeviceHandler() *DeviceHandler {
+	device := &voltha.Device{
+		Id:       "olt",
+		Root:     true,
+		ParentId: "logical_device",
+		Ports: []*voltha.Port{
+			{PortNo: 1, Label: "pon", Type: voltha.Port_PON_OLT},
+			{PortNo: 2, Label: "nni", Type: voltha.Port_ETHERNET_NNI},
+		},
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "olt",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+	}
+	cp := newMockCoreProxy()
+	ap := &mocks.MockAdapterProxy{}
+	ep := &mocks.MockEventProxy{}
+	openOLT := &OpenOLT{coreProxy: cp, adapterProxy: ap, eventProxy: ep}
+	dh := NewDeviceHandler(cp, ap, ep, device, openOLT)
+	deviceInf := &oop.DeviceInfo{Vendor: "openolt", Ranges: nil, Model: "openolt", DeviceId: dh.deviceID}
+	dh.resourceMgr = &resourcemanager.OpenOltResourceMgr{DeviceID: dh.deviceID, DeviceType: dh.deviceType, DevInfo: deviceInf,
+		KVStore: &db.Backend{
+			Client: &mocks.MockKVClient{},
+		}}
+	dh.resourceMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager)
+	ranges := make(map[string]interface{})
+	sharedIdxByType := make(map[string]string)
+	sharedIdxByType["ALLOC_ID"] = "ALLOC_ID"
+	sharedIdxByType["ONU_ID"] = "ONU_ID"
+	sharedIdxByType["GEMPORT_ID"] = "GEMPORT_ID"
+	sharedIdxByType["FLOW_ID"] = "FLOW_ID"
+	ranges["ONU_ID"] = uint32(0)
+	ranges["GEMPORT_ID"] = uint32(0)
+	ranges["ALLOC_ID"] = uint32(0)
+	ranges["FLOW_ID"] = uint32(0)
+	ranges["onu_id_shared"] = uint32(0)
+	ranges["alloc_id_shared"] = uint32(0)
+	ranges["gemport_id_shared"] = uint32(0)
+	ranges["flow_id_shared"] = uint32(0)
+
+	ponmgr := &ponrmgr.PONResourceManager{
+		DeviceID: "onu-1",
+		IntfIDs:  []uint32{1, 2},
+		KVStore: &db.Backend{
+			Client: &mocks.MockKVClient{},
+		},
+		PonResourceRanges: ranges,
+		SharedIdxByType:   sharedIdxByType,
+	}
+	dh.resourceMgr.ResourceMgrs[1] = ponmgr
+	dh.resourceMgr.ResourceMgrs[2] = ponmgr
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	dh.flowMgr = NewFlowManager(ctx, dh, dh.resourceMgr)
+	dh.Client = &mocks.MockOpenoltClient{}
+	dh.eventMgr = &OpenOltEventMgr{eventProxy: &mocks.MockEventProxy{}, handler: dh}
+	dh.transitionMap = &TransitionMap{}
+	dh.portStats = &OpenOltStatisticsMgr{}
+
+	var pmNames = []string{
+		"rx_bytes",
+		"rx_packets",
+		"rx_mcast_packets",
+		"rx_bcast_packets",
+		"tx_bytes",
+		"tx_packets",
+		"tx_mcast_packets",
+		"tx_bcast_packets",
+	}
+
+	dh.metrics = pmmetrics.NewPmMetrics(device.Id, pmmetrics.Frequency(2), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
+	return dh
+}
+
+func negativeDeviceHandler() *DeviceHandler {
+	dh := newMockDeviceHandler()
+	device := dh.device
+	device.Id = ""
+	dh.adminState = "down"
+	return dh
+}
+func Test_generateMacFromHost(t *testing.T) {
+	type args struct {
+		host string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    string
+		wantErr bool
+	}{
+		{"generateMacFromHost-1", args{host: "localhost"}, "00:00:7f:00:00:01", false},
+		{"generateMacFromHost-2", args{host: "10.10.10.10"}, "00:00:0a:0a:0a:0a", false},
+		//{"generateMacFromHost-3", args{host: "google.com"}, "00:00:d8:3a:c8:8e", false},
+		{"generateMacFromHost-4", args{host: "testing3"}, "", true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := generateMacFromHost(tt.args.host)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("generateMacFromHost() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("generateMacFromHost() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+func Test_macifyIP(t *testing.T) {
+	type args struct {
+		ip net.IP
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{{
+		"macifyIP-1",
+		args{ip: net.ParseIP("10.10.10.10")},
+		"00:00:0a:0a:0a:0a",
+	},
+		{
+			"macifyIP-2",
+			args{ip: net.ParseIP("127.0.0.1")},
+			"00:00:7f:00:00:01",
+		},
+		{
+			"macifyIP-3",
+			args{ip: net.ParseIP("127.0.0.1/24")},
+			"",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := macifyIP(tt.args.ip); got != tt.want {
+				t.Errorf("macifyIP() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func sparseCompare(keys []string, spec, target interface{}) bool {
+	if spec == target {
+		return true
+	}
+	if spec == nil || target == nil {
+		return false
+	}
+	typeSpec := reflect.TypeOf(spec)
+	typeTarget := reflect.TypeOf(target)
+	if typeSpec != typeTarget {
+		return false
+	}
+
+	vSpec := reflect.ValueOf(spec)
+	vTarget := reflect.ValueOf(target)
+	if vSpec.Kind() == reflect.Ptr {
+		vSpec = vSpec.Elem()
+		vTarget = vTarget.Elem()
+	}
+
+	for _, key := range keys {
+		fSpec := vSpec.FieldByName(key)
+		fTarget := vTarget.FieldByName(key)
+		if !reflect.DeepEqual(fSpec.Interface(), fTarget.Interface()) {
+			return false
+		}
+	}
+	return true
+}
+
+func TestDeviceHandler_GetChildDevice(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		parentPort uint32
+		onuID      uint32
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		want          *voltha.Device
+		errType       reflect.Type
+	}{
+		{"GetChildDevice-1", dh1,
+			args{parentPort: 1,
+				onuID: 1},
+			&voltha.Device{
+				Id:           "1",
+				ParentId:     "olt",
+				ParentPortNo: 1,
+			},
+			nil,
+		},
+		{"GetChildDevice-2", dh2,
+			args{parentPort: 1,
+				onuID: 1},
+			nil,
+			reflect.TypeOf(&ErrNotFound{}),
+		},
+	}
+
+	/*
+	   --- FAIL: TestDeviceHandler_GetChildDevice/GetChildDevice-1 (0.00s)
+	       device_handler_test.go:309: GetportLabel() => want=(, <nil>) got=(id:"1" parent_id:"olt" parent_port_no:1 proxy_address:<channel_id:1 channel_group_id:1 onu_id:1 > oper_status:ACTIVE connect_status:UNREACHABLE ports:<port_no:1 label:"pon" > ports:<port_no:2 label:"uni" > pm_configs:<id:"olt" default_freq:10 > , <nil>)
+	   --- FAIL: TestDeviceHandler_GetChildDevice/GetChildDevice-2 (0.00s)
+	*/
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := tt.devicehandler.GetChildDevice(tt.args.parentPort, tt.args.onuID)
+			if reflect.TypeOf(err) != tt.errType || !sparseCompare([]string{"Id", "ParentId", "ParentPortNo"}, tt.want, got) {
+				t.Errorf("GetportLabel() => want=(%v, %v) got=(%v, %v)",
+					tt.want, tt.errType, got, reflect.TypeOf(err))
+				return
+			}
+			t.Log("onu device id", got)
+		})
+	}
+}
+
+func TestGetportLabel(t *testing.T) {
+	invalid := reflect.TypeOf(&ErrInvalidValue{})
+	type args struct {
+		portNum  uint32
+		portType voltha.Port_PortType
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    string
+		errType reflect.Type
+	}{
+		{"GetportLabel-1", args{portNum: 0, portType: 0}, "", invalid},
+		{"GetportLabel-2", args{portNum: 1, portType: 1}, "nni-1", nil},
+		{"GetportLabel-3", args{portNum: 2, portType: 2}, "", invalid},
+		{"GetportLabel-4", args{portNum: 3, portType: 3}, "pon-3", nil},
+		{"GetportLabel-5", args{portNum: 4, portType: 4}, "", invalid},
+		{"GetportLabel-6", args{portNum: 5, portType: 5}, "", invalid},
+		{"GetportLabel-7", args{portNum: 6, portType: 6}, "", invalid},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetportLabel(tt.args.portNum, tt.args.portType)
+			if reflect.TypeOf(err) != tt.errType || got != tt.want {
+				t.Errorf("GetportLabel() => want=(%v, %v) got=(%v, %v)",
+					tt.want, tt.errType, got, reflect.TypeOf(err))
+			}
+
+		})
+	}
+}
+
+func TestDeviceHandler_ProcessInterAdapterMessage(t *testing.T) {
+	dh := newMockDeviceHandler()
+	proxyAddr := dh.device.ProxyAddress
+	body := &ic.InterAdapterOmciMessage{
+		Message:      []byte("asdfasdfasdfasdfas"),
+		ProxyAddress: proxyAddr,
+	}
+	body2 := &ic.InterAdapterOmciMessage{
+		Message: []byte("asdfasdfasdfasdfas"),
+		//ProxyAddress: &voltha.Device_ProxyAddress{},
+	}
+	body3 := &ic.InterAdapterTechProfileDownloadMessage{}
+	var marshalledData *any.Any
+	var err error
+
+	if marshalledData, err = ptypes.MarshalAny(body); err != nil {
+		log.Errorw("cannot-marshal-request", log.Fields{"error": err})
+	}
+
+	var marshalledData1 *any.Any
+
+	if marshalledData1, err = ptypes.MarshalAny(body2); err != nil {
+		log.Errorw("cannot-marshal-request", log.Fields{"error": err})
+	}
+	var marshalledData2 *any.Any
+
+	if marshalledData2, err = ptypes.MarshalAny(body3); err != nil {
+		log.Errorw("cannot-marshal-request", log.Fields{"error": err})
+	}
+	type args struct {
+		msg *ic.InterAdapterMessage
+	}
+	invalid := reflect.TypeOf(&ErrInvalidValue{})
+	tests := []struct {
+		name    string
+		args    args
+		wantErr reflect.Type
+	}{
+		{"ProcessInterAdapterMessage-1", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_FLOW_REQUEST,
+			},
+			Body: marshalledData,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-2", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_FLOW_RESPONSE,
+			},
+			Body: marshalledData1,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-3", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_OMCI_REQUEST,
+			},
+			Body: marshalledData,
+		}}, reflect.TypeOf(&ErrCommunication{})},
+		{"ProcessInterAdapterMessage-4", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_OMCI_RESPONSE,
+			}, Body: marshalledData,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-5", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_METRICS_REQUEST,
+			}, Body: marshalledData1,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-6", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_METRICS_RESPONSE,
+			}, Body: marshalledData,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-7", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_ONU_IND_REQUEST,
+			}, Body: marshalledData,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-8", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_ONU_IND_RESPONSE,
+			}, Body: marshalledData,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-9", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST,
+			}, Body: marshalledData,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-10", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
+			}, Body: marshalledData2,
+		}}, invalid},
+		{"ProcessInterAdapterMessage-11", args{msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:   "012345",
+				Type: ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
+			}, Body: marshalledData2,
+		}}, invalid},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			if err := dh.ProcessInterAdapterMessage(tt.args.msg); reflect.TypeOf(err) != tt.wantErr {
+				t.Errorf("DeviceHandler.ProcessInterAdapterMessage() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_sendProxiedMessage(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	device1 := &voltha.Device{
+		Id:       "onu1",
+		Root:     false,
+		ParentId: "logical_device",
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "onu1",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+	}
+	device2 := device1
+	device2.ConnectStatus = 2
+	iaomciMsg1 := &ic.InterAdapterOmciMessage{
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "onu2",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+			//OnuId:          2,
+		},
+		ConnectStatus: 1,
+	}
+	iaomciMsg2 := &ic.InterAdapterOmciMessage{
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "onu3",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+	}
+	type args struct {
+		onuDevice *voltha.Device
+		omciMsg   *ic.InterAdapterOmciMessage
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+	}{
+		{"sendProxiedMessage-1", dh1, args{onuDevice: device1, omciMsg: &ic.InterAdapterOmciMessage{}}},
+		{"sendProxiedMessage-2", dh1, args{onuDevice: device2, omciMsg: &ic.InterAdapterOmciMessage{}}},
+		{"sendProxiedMessage-3", dh1, args{onuDevice: nil, omciMsg: iaomciMsg1}},
+		{"sendProxiedMessage-4", dh1, args{onuDevice: nil, omciMsg: iaomciMsg2}},
+		{"sendProxiedMessage-5", dh2, args{onuDevice: nil, omciMsg: iaomciMsg2}},
+		{"sendProxiedMessage-6", dh2, args{onuDevice: device1, omciMsg: &ic.InterAdapterOmciMessage{}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.devicehandler.sendProxiedMessage(tt.args.onuDevice, tt.args.omciMsg)
+		})
+	}
+}
+
+func TestDeviceHandler_SendPacketInToCore(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+
+	type args struct {
+		logicalPort   uint32
+		packetPayload []byte
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+	}{
+		{"SendPacketInToCore-1", dh1, args{logicalPort: 1, packetPayload: []byte("test1")}},
+		{"SendPacketInToCore-2", dh1, args{logicalPort: 1, packetPayload: []byte("")}},
+		{"SendPacketInToCore-3", dh2, args{logicalPort: 1, packetPayload: []byte("test1")}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.devicehandler.SendPacketInToCore(tt.args.logicalPort, tt.args.packetPayload)
+		})
+	}
+}
+
+func TestDeviceHandler_DisableDevice(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		wantErr       bool
+	}{
+		{"DisableDevice-1", dh1, args{device: dh1.device}, false},
+		{"DisableDevice-2", dh1, args{device: dh2.device}, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			if err := tt.devicehandler.DisableDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.DisableDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_ReenableDevice(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		wantErr       bool
+	}{
+		{"ReenableDevice-1", dh1, args{device: dh1.device}, false},
+		{"ReenableDevice-2", dh1, args{device: &voltha.Device{}}, true},
+		{"ReenableDevice-3", dh2, args{device: dh1.device}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dh := tt.devicehandler
+			if err := dh.ReenableDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.ReenableDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_RebootDevice(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := newMockDeviceHandler()
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		wantErr       bool
+	}{
+		// TODO: Add test cases.
+		{"RebootDevice-1", dh1, args{device: dh1.device}, false},
+		{"RebootDevice-2", dh1, args{device: dh2.device}, true},
+		{"RebootDevice-3", dh2, args{device: dh2.device}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			if err := tt.devicehandler.RebootDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.RebootDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_handleIndication(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	dh3 := newMockDeviceHandler()
+	dh3.onus = sync.Map{}
+	dh3.onus.Store("onu1", NewOnuDevice("onu1", "onu1", "onu1", 1, 1, "onu1"))
+	dh3.onus.Store("onu2", NewOnuDevice("onu2", "onu2", "onu2", 2, 2, "onu2"))
+
+	type args struct {
+		indication *oop.Indication
+	}
+	tests := []struct {
+		name          string
+		deviceHandler *DeviceHandler
+		args          args
+	}{
+		// TODO: Add test cases.
+		{"handleIndication-1", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OltInd{OltInd: &oop.OltIndication{OperState: "up"}}}}},
+		{"handleIndication-2", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OltInd{OltInd: &oop.OltIndication{OperState: "down"}}}}},
+		{"handleIndication-3", dh1, args{indication: &oop.Indication{Data: &oop.Indication_IntfInd{IntfInd: &oop.IntfIndication{IntfId: 1, OperState: "up"}}}}},
+		{"handleIndication-4", dh1, args{indication: &oop.Indication{Data: &oop.Indication_IntfInd{IntfInd: &oop.IntfIndication{IntfId: 1, OperState: "down"}}}}},
+		{"handleIndication-5", dh1, args{indication: &oop.Indication{Data: &oop.Indication_IntfOperInd{IntfOperInd: &oop.IntfOperIndication{Type: "nni", IntfId: 1, OperState: "up"}}}}},
+		{"handleIndication-6", dh1, args{indication: &oop.Indication{Data: &oop.Indication_IntfOperInd{IntfOperInd: &oop.IntfOperIndication{Type: "pon", IntfId: 1, OperState: "up"}}}}},
+		{"handleIndication-7", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OnuDiscInd{OnuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}}}}},
+		{"handleIndication-8", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "up", AdminState: "up"}}}}},
+		{"handleIndication-9", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "up", AdminState: "down"}}}}},
+		{"handleIndication-10", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "down", AdminState: "up"}}}}},
+		{"handleIndication-11", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "down", AdminState: "down"}}}}},
+		{"handleIndication-12", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OmciInd{OmciInd: &oop.OmciIndication{IntfId: 1, OnuId: 1, Pkt: []byte("onu123-random value")}}}}},
+		{"handleIndication-13", dh1, args{indication: &oop.Indication{Data: &oop.Indication_PktInd{PktInd: &oop.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 1234, PortNo: 1}}}}},
+		{"handleIndication-14", dh1, args{indication: &oop.Indication{Data: &oop.Indication_PortStats{PortStats: &oop.PortStatistics{IntfId: 1, RxBytes: 100, RxPackets: 100, RxUcastPackets: 100, RxMcastPackets: 100, RxBcastPackets: 100, RxErrorPackets: 100, TxBytes: 100, TxPackets: 100, TxUcastPackets: 100, TxMcastPackets: 100, TxBcastPackets: 100, TxErrorPackets: 100, RxCrcErrors: 100, BipErrors: 100, Timestamp: 1000}}}}},
+		{"handleIndication-15", dh1, args{indication: &oop.Indication{Data: &oop.Indication_FlowStats{FlowStats: &oop.FlowStatistics{RxBytes: 100, RxPackets: 100, TxBytes: 100, TxPackets: 100, Timestamp: 1000}}}}},
+		{"handleIndication-16", dh1, args{indication: &oop.Indication{Data: &oop.Indication_AlarmInd{AlarmInd: &oop.AlarmIndication{}}}}},
+		{"handleIndication-17", dh1, args{indication: &oop.Indication{Data: &oop.Indication_PktInd{PktInd: &oop.PacketIndication{IntfType: "nni", FlowId: 1234, PortNo: 1}}}}},
+		{"handleIndication-18", dh1, args{indication: &oop.Indication{Data: &oop.Indication_PktInd{PktInd: &oop.PacketIndication{}}}}},
+
+		// Negative testcases
+		{"handleIndication-19", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OltInd{OltInd: &oop.OltIndication{OperState: "up"}}}}},
+		{"handleIndication-20", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OltInd{OltInd: &oop.OltIndication{OperState: "down"}}}}},
+		{"handleIndication-21", dh2, args{indication: &oop.Indication{Data: &oop.Indication_IntfInd{IntfInd: &oop.IntfIndication{IntfId: 1, OperState: "up"}}}}},
+		{"handleIndication-22", dh2, args{indication: &oop.Indication{Data: &oop.Indication_IntfInd{IntfInd: &oop.IntfIndication{IntfId: 1, OperState: "down"}}}}},
+		{"handleIndication-23", dh2, args{indication: &oop.Indication{Data: &oop.Indication_IntfOperInd{IntfOperInd: &oop.IntfOperIndication{Type: "nni", IntfId: 1, OperState: "up"}}}}},
+		{"handleIndication-24", dh2, args{indication: &oop.Indication{Data: &oop.Indication_IntfOperInd{IntfOperInd: &oop.IntfOperIndication{Type: "pon", IntfId: 1, OperState: "up"}}}}},
+		{"handleIndication-25", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OnuDiscInd{OnuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}}}}},
+		{"handleIndication-26", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "up", AdminState: "up"}}}}},
+		{"handleIndication-27", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "up", AdminState: "down"}}}}},
+		{"handleIndication-28", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "down", AdminState: "up"}}}}},
+		{"handleIndication-29", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "down", AdminState: "down"}}}}},
+		{"handleIndication-30", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OmciInd{OmciInd: &oop.OmciIndication{IntfId: 1, OnuId: 1, Pkt: []byte("onu123-random value")}}}}},
+		{"handleIndication-31", dh2, args{indication: &oop.Indication{Data: &oop.Indication_PktInd{PktInd: &oop.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 1234, PortNo: 1}}}}},
+		{"handleIndication-32", dh2, args{indication: &oop.Indication{Data: &oop.Indication_PortStats{PortStats: &oop.PortStatistics{IntfId: 1, RxBytes: 100, RxPackets: 100, RxUcastPackets: 100, RxMcastPackets: 100, RxBcastPackets: 100, RxErrorPackets: 100, TxBytes: 100, TxPackets: 100, TxUcastPackets: 100, TxMcastPackets: 100, TxBcastPackets: 100, TxErrorPackets: 100, RxCrcErrors: 100, BipErrors: 100, Timestamp: 1000}}}}},
+		{"handleIndication-33", dh2, args{indication: &oop.Indication{Data: &oop.Indication_FlowStats{FlowStats: &oop.FlowStatistics{RxBytes: 100, RxPackets: 100, TxBytes: 100, TxPackets: 100, Timestamp: 1000}}}}},
+		{"handleIndication-34", dh2, args{indication: &oop.Indication{Data: &oop.Indication_AlarmInd{AlarmInd: &oop.AlarmIndication{}}}}},
+		//
+		{"handleIndication-35", dh3, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "up", AdminState: "up"}}}}},
+		{"handleIndication-36", dh3, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "down", AdminState: "up"}}}}},
+		{"handleIndication-37", dh3, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "up", AdminState: "down"}}}}},
+		{"handleIndication-38", dh3, args{indication: &oop.Indication{Data: &oop.Indication_OnuInd{OnuInd: &oop.OnuIndication{IntfId: 1, OnuId: 1, OperState: "down", AdminState: "down"}}}}},
+		{"handleIndication-30", dh1, args{indication: &oop.Indication{Data: &oop.Indication_OmciInd{OmciInd: &oop.OmciIndication{IntfId: 1, OnuId: 4, Pkt: []byte("onu123-random value")}}}}},
+		{"handleIndication-30", dh2, args{indication: &oop.Indication{Data: &oop.Indication_OmciInd{OmciInd: &oop.OmciIndication{IntfId: 1, OnuId: 4, Pkt: []byte("onu123-random value")}}}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dh := tt.deviceHandler
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			dh.handleIndication(ctx, tt.args.indication)
+		})
+	}
+}
+
+func TestDeviceHandler_addPort(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		intfID   uint32
+		portType voltha.Port_PortType
+		state    string
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+	}{
+		// State up
+		{"addPort.1", dh1, args{intfID: 1, portType: voltha.Port_UNKNOWN, state: "up"}},
+		{"addPort.2", dh1, args{intfID: 1, portType: voltha.Port_VENET_OLT, state: "up"}},
+		{"addPort.3", dh1, args{intfID: 1, portType: voltha.Port_VENET_ONU, state: "up"}},
+		{"addPort.4", dh1, args{intfID: 1, portType: voltha.Port_ETHERNET_NNI, state: "up"}},
+		{"addPort.5", dh1, args{intfID: 1, portType: voltha.Port_ETHERNET_UNI, state: "up"}},
+		{"addPort.6", dh1, args{intfID: 1, portType: voltha.Port_PON_OLT, state: "up"}},
+		{"addPort.7", dh1, args{intfID: 1, portType: voltha.Port_PON_ONU, state: "up"}},
+		{"addPort.8", dh1, args{intfID: 1, portType: 8, state: "up"}},
+		// state discovery
+		{"addPort.9", dh1, args{intfID: 1, portType: voltha.Port_UNKNOWN, state: "down"}},
+		{"addPort.10", dh1, args{intfID: 1, portType: voltha.Port_VENET_OLT, state: "down"}},
+		{"addPort.11", dh1, args{intfID: 1, portType: voltha.Port_VENET_ONU, state: "down"}},
+		{"addPort.12", dh1, args{intfID: 1, portType: voltha.Port_ETHERNET_NNI, state: "down"}},
+		{"addPort.13", dh1, args{intfID: 1, portType: voltha.Port_ETHERNET_UNI, state: "down"}},
+		{"addPort.14", dh1, args{intfID: 1, portType: voltha.Port_PON_OLT, state: "down"}},
+		{"addPort.15", dh1, args{intfID: 1, portType: voltha.Port_PON_ONU, state: "down"}},
+		{"addPort.16", dh1, args{intfID: 1, portType: 8, state: "down"}},
+
+		{"addPort.17", dh2, args{intfID: 1, portType: voltha.Port_ETHERNET_NNI, state: "up"}},
+		{"addPort.18", dh2, args{intfID: 1, portType: voltha.Port_ETHERNET_UNI, state: "up"}},
+		{"addPort.19", dh2, args{intfID: 1, portType: voltha.Port_ETHERNET_NNI, state: "down"}},
+		{"addPort.20", dh2, args{intfID: 1, portType: voltha.Port_ETHERNET_UNI, state: "down"}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.devicehandler.addPort(tt.args.intfID, tt.args.portType, tt.args.state)
+		})
+	}
+}
+
+func Test_macAddressToUint32Array(t *testing.T) {
+	type args struct {
+		mac string
+	}
+	tests := []struct {
+		name string
+		args args
+		want []uint32
+	}{
+		// TODO: Add test cases.
+		{"macAddressToUint32Array-1", args{mac: "00:00:00:00:00:01"}, []uint32{0, 0, 0, 0, 0, 1}},
+		{"macAddressToUint32Array-2", args{mac: "0abcdef"}, []uint32{11259375}},
+		{"macAddressToUint32Array-3", args{mac: "testing"}, []uint32{1, 2, 3, 4, 5, 6}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := macAddressToUint32Array(tt.args.mac); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("macAddressToUint32Array() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_handleOltIndication(t *testing.T) {
+
+	type args struct {
+		oltIndication *oop.OltIndication
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{"handleOltIndication-1", args{oltIndication: &oop.OltIndication{OperState: "up"}}},
+		{"handleOltIndication-2", args{oltIndication: &oop.OltIndication{OperState: "down"}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dh := newMockDeviceHandler()
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			dh.handleOltIndication(ctx, tt.args.oltIndication)
+		})
+	}
+}
+
+func TestDeviceHandler_AdoptDevice(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+	}{
+		// TODO: Add test cases.
+		{"AdoptDevice-1", dh1, args{device: dh1.device}},
+		{"AdoptDevice-2", dh2, args{device: dh2.device}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			//dh.doStateInit()
+			//	context.
+			//dh.AdoptDevice(tt.args.device)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			tt.devicehandler.postInit(ctx)
+		})
+	}
+}
+
+func TestDeviceHandler_activateONU(t *testing.T) {
+	dh := newMockDeviceHandler()
+	dh1 := negativeDeviceHandler()
+	type args struct {
+		intfID       uint32
+		onuID        int64
+		serialNum    *oop.SerialNumber
+		serialNumber string
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+	}{
+		{"activateONU-1", dh, args{intfID: 1, onuID: 1, serialNum: &oop.SerialNumber{VendorId: []byte("onu1")}}},
+		{"activateONU-2", dh, args{intfID: 2, onuID: 2, serialNum: &oop.SerialNumber{VendorId: []byte("onu2")}}},
+		{"activateONU-3", dh1, args{intfID: 1, onuID: 1, serialNum: &oop.SerialNumber{VendorId: []byte("onu1")}}},
+		{"activateONU-4", dh1, args{intfID: 2, onuID: 2, serialNum: &oop.SerialNumber{VendorId: []byte("onu2")}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			tt.devicehandler.activateONU(ctx, tt.args.intfID, tt.args.onuID,
+				tt.args.serialNum, tt.args.serialNumber)
+		})
+	}
+}
+
+func TestDeviceHandler_start(t *testing.T) {
+	dh := newMockDeviceHandler()
+	dh1 := negativeDeviceHandler()
+	dh.start(context.Background())
+	dh.stop(context.Background())
+
+	dh1.start(context.Background())
+	dh1.stop(context.Background())
+
+}
+
+func TestDeviceHandler_PacketOut(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	acts := []*ofp.OfpAction{
+		fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA))),
+		fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+		fu.Output(1),
+	}
+	pktout := &ofp.OfpPacketOut{BufferId: 0, InPort: 1, Actions: acts, Data: []byte("AYDCAAAOAODsSE5TiMwCBwQA4OxITlIEBQUwLzUxBgIAFAgEMC81MQoJbG9jYWxob3N0EBwFAawbqqACAAAAoRAxLjMuNi4xLjQuMS40NDEz/gYAgMILAgD+GQCAwgkDAAAAAGQAAAAAAAAAAgICAgICAgL+GQCAwgoDAAAAAGQAAAAAAAAAAgICAgICAgIAAA==")}
+	type args struct {
+		egressPortNo int
+		packet       *of.OfpPacketOut
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		wantErr       bool
+	}{
+		// TODO: Add test cases.
+		//{"test1", args{egressPortNo: 0, packet: &ofp.OfpPacketOut{}}, true},
+		{"PacketOut-1", dh1, args{egressPortNo: 0, packet: pktout}, false},
+		{"PacketOut-2", dh2, args{egressPortNo: 1, packet: pktout}, false},
+		{"PacketOut-2", dh2, args{egressPortNo: 115000, packet: pktout}, false},
+		{"PacketOut-3", dh1, args{egressPortNo: 65536, packet: pktout}, false},
+		{"PacketOut-4", dh2, args{egressPortNo: 65535, packet: pktout}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dh := tt.devicehandler
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := dh.PacketOut(ctx, tt.args.egressPortNo, tt.args.packet); (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.PacketOut() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+//
+func TestDeviceHandler_doStateUp(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := newMockDeviceHandler()
+
+	dh2.deviceID = ""
+	dh3 := negativeDeviceHandler()
+
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		wantErr       bool
+	}{
+		{"dostateup-1", dh1, false},
+		{"dostateup-2", dh2, false},
+		{"dostateup-3", dh3, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := tt.devicehandler.doStateUp(ctx); (err != nil) != tt.wantErr {
+				t.Logf("DeviceHandler.doStateUp() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+func TestDeviceHandler_doStateDown(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	dh3 := newMockDeviceHandler()
+	dh3.device.OperStatus = voltha.OperStatus_UNKNOWN
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		wantErr       bool
+	}{
+		{"dostatedown-1", dh1, false},
+		{"dostatedown-2", dh2, true},
+		{"dostatedown-2", dh3, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := tt.devicehandler.doStateDown(ctx); (err != nil) != tt.wantErr {
+				t.Logf("DeviceHandler.doStateDown() error = %v", err)
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_GetOfpDeviceInfo(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		wantErr       bool
+	}{
+		// TODO: Add test cases.
+		{"GetOfpDeviceInfo-1", dh1, args{dh1.device}, false},
+		{"GetOfpDeviceInfo-2", dh1, args{&voltha.Device{}}, false},
+		{"GetOfpDeviceInfo-3", dh2, args{dh1.device}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dh := tt.devicehandler
+			_, err := dh.GetOfpDeviceInfo(tt.args.device)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.GetOfpDeviceInfo() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_GetOfpPortInfo(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		device *voltha.Device
+		portNo int64
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+		wantErr       bool
+	}{
+		{"GetOfpPortInfo-1", dh1, args{device: dh1.device, portNo: 1}, false},
+		{"GetOfpPortInfo-2", dh2, args{device: dh2.device, portNo: 1}, false},
+		{"GetOfpPortInfo-3", dh1, args{device: dh1.device, portNo: 0}, false},
+		{"GetOfpPortInfo-4", dh2, args{device: dh2.device, portNo: 0}, false},
+		{"GetOfpPortInfo-5", dh1, args{device: &voltha.Device{}, portNo: 1}, false},
+		{"GetOfpPortInfo-6", dh2, args{device: &voltha.Device{}, portNo: 0}, false},
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dh := tt.devicehandler
+			_, err := dh.GetOfpPortInfo(tt.args.device, tt.args.portNo)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.GetOfpPortInfo() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+		})
+	}
+}
+
+func TestDeviceHandler_onuDiscIndication(t *testing.T) {
+
+	dh1 := newMockDeviceHandler()
+	dh1.discOnus = sync.Map{}
+	dh1.discOnus.Store("onu1", true)
+	dh1.discOnus.Store("onu2", false)
+	dh2 := negativeDeviceHandler()
+	type args struct {
+		onuDiscInd *oop.OnuDiscIndication
+		sn         string
+	}
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+		args          args
+	}{
+		// TODO: Add test cases.
+		{"onuDiscIndication-1", dh1, args{onuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}}},
+		{"onuDiscIndication-2", dh1, args{onuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{}}}},
+		{"onuDiscIndication-3", dh1, args{onuDiscInd: &oop.OnuDiscIndication{SerialNumber: &oop.SerialNumber{}}}},
+		{"onuDiscIndication-4", dh1, args{onuDiscInd: &oop.OnuDiscIndication{}}},
+		{"onuDiscIndication-5", dh1, args{onuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}, sn: "onu1"}},
+		{"onuDiscIndication-6", dh1, args{onuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}, sn: "onu2"}},
+		{"onuDiscIndication-7", dh2, args{onuDiscInd: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			tt.devicehandler.onuDiscIndication(ctx, tt.args.onuDiscInd, tt.args.sn)
+		})
+	}
+}
+
+func TestDeviceHandler_populateDeviceInfo(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := negativeDeviceHandler()
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"populateDeviceInfo-1", dh1, false},
+		{"populateDeviceInfo-2", dh1, true},
+		{"populateDeviceInfo-3", dh1, true},
+		{"populateDeviceInfo-4", dh1, true},
+		{"populateDeviceInfo-5", dh2, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			_, err := tt.devicehandler.populateDeviceInfo()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("DeviceHandler.populateDeviceInfo() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+		})
+	}
+}
+
+func TestDeviceHandler_readIndications(t *testing.T) {
+	dh1 := newMockDeviceHandler()
+	dh2 := newMockDeviceHandler()
+	dh2.adminState = "down"
+	dh3 := newMockDeviceHandler()
+	dh3.device.AdminState = voltha.AdminState_DISABLED
+	dh4 := negativeDeviceHandler()
+	tests := []struct {
+		name          string
+		devicehandler *DeviceHandler
+	}{
+		// TODO: Add test cases.
+		{"readIndications-1", dh1},
+		{"readIndications-2", dh2},
+		{"readIndications-3", dh2},
+		{"readIndications-4", dh2},
+		{"readIndications-5", dh2},
+		{"readIndications-6", dh3},
+		{"readIndications-7", dh3},
+		{"readIndications-8", dh4},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			tt.devicehandler.readIndications(ctx)
+		})
+	}
+}
+
+func Test_startCollector(t *testing.T) {
+	type args struct {
+		dh *DeviceHandler
+	}
+	dh := newMockDeviceHandler()
+	dh.portStats.NorthBoundPort = make(map[uint32]*NniPort)
+	dh.portStats.NorthBoundPort[0] = &NniPort{Name: "OLT-1"}
+	dh.portStats.SouthBoundPort = make(map[uint32]*PonPort)
+	dh.portStats.Device = dh
+	for i := 0; i < 16; i++ {
+		dh.portStats.SouthBoundPort[uint32(i)] = &PonPort{DeviceID: "OLT-1"}
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		{"StartCollector-1", args{dh}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			go func() {
+				time.Sleep(66 * time.Second) // startCollector inside waits for 1 min, so we stop it after 6 secs of running
+				tt.args.dh.stopCollector <- true
+			}()
+			startCollector(tt.args.dh)
+		})
+	}
+}
diff --git a/internal/pkg/core/error.go b/internal/pkg/core/error.go
new file mode 100644
index 0000000..0de7dc8
--- /dev/null
+++ b/internal/pkg/core/error.go
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2020-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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"strings"
+)
+
+const (
+	defaultLogAndReturnLevel = log.DebugLevel
+)
+
+func copy(src log.Fields) log.Fields {
+	dst := make(log.Fields)
+	for k, v := range src {
+		dst[k] = v
+	}
+	return dst
+}
+
+func merge(one, two log.Fields) log.Fields {
+	dst := make(log.Fields)
+	for k, v := range one {
+		dst[k] = v
+	}
+	for k, v := range two {
+		dst[k] = v
+	}
+	return dst
+}
+
+// LoggableError defined functions that can be used to log an object
+type LoggableError interface {
+	error
+	Log() error
+	LogAt(log.LogLevel) error
+}
+
+// ErrAdapter represents a basic adapter error that combines an name, field set
+// and wrapped error
+type ErrAdapter struct {
+	name    string
+	fields  log.Fields
+	wrapped error
+}
+
+// NewErrAdapter constructs a new error with the given values
+func NewErrAdapter(name string, fields log.Fields, wrapped error) LoggableError {
+	return &ErrAdapter{
+		name:    name,
+		fields:  copy(fields),
+		wrapped: wrapped,
+	}
+}
+
+// Name returns the error name
+func (e *ErrAdapter) Name() string {
+	return e.name
+}
+
+// Fields returns the fields associated with the error
+func (e *ErrAdapter) Fields() log.Fields {
+	return e.fields
+}
+
+// Unwrap returns the wrapped or nested error
+func (e *ErrAdapter) Unwrap() error {
+	return e.wrapped
+}
+
+// Error returns a string representation of the error
+func (e *ErrAdapter) Error() string {
+	var buf strings.Builder
+	buf.WriteString(e.name)
+	if len(e.fields) > 0 {
+		if val, err := json.Marshal(e.fields); err == nil {
+			buf.WriteString(": [")
+			buf.WriteString(string(val))
+			buf.WriteString("]")
+		}
+	}
+	if e.wrapped != nil {
+		buf.WriteString(": ")
+		buf.WriteString(e.wrapped.Error())
+	}
+	return buf.String()
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrAdapter) Log() error {
+	return e.LogAt(defaultLogAndReturnLevel)
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrAdapter) LogAt(level log.LogLevel) error {
+	logger := log.Debugw
+	switch level {
+	case log.InfoLevel:
+		logger = log.Infow
+	case log.WarnLevel:
+		logger = log.Warnw
+	case log.ErrorLevel:
+		logger = log.Errorw
+	case log.FatalLevel:
+		logger = log.Fatalw
+	}
+	local := e.fields
+	if e.wrapped != nil {
+		local = merge(e.fields, log.Fields{"wrapped": e.wrapped})
+	}
+	logger(e.name, local)
+	return e
+}
+
+// ErrInvalidValue represents an error condition with given value is not able to
+// be processed
+type ErrInvalidValue struct {
+	ErrAdapter
+}
+
+// NewErrInvalidValue constructs a new error based on the given values
+func NewErrInvalidValue(fields log.Fields, wrapped error) LoggableError {
+	return &ErrInvalidValue{
+		ErrAdapter{
+			name:    "invalid-value",
+			fields:  copy(fields),
+			wrapped: wrapped,
+		},
+	}
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrInvalidValue) Log() error {
+	_ = e.ErrAdapter.Log()
+	return e
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrInvalidValue) LogAt(level log.LogLevel) error {
+	_ = e.ErrAdapter.LogAt(level)
+	return e
+}
+
+// ErrNotFound represents an error condition when a value can not be located
+// given a field set of criteria
+type ErrNotFound struct {
+	ErrAdapter
+}
+
+// NewErrNotFound constructs a new error based on the given values
+func NewErrNotFound(target string, fields log.Fields, wrapped error) LoggableError {
+	return &ErrNotFound{
+		ErrAdapter{
+			name:    "not-found",
+			fields:  merge(fields, log.Fields{"target": target}),
+			wrapped: wrapped,
+		},
+	}
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrNotFound) Log() error {
+	_ = e.ErrAdapter.Log()
+	return e
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrNotFound) LogAt(level log.LogLevel) error {
+	_ = e.ErrAdapter.LogAt(level)
+	return e
+}
+
+// ErrPersistence representation an error condition when a persistence operation
+// did not succeed
+type ErrPersistence struct {
+	ErrAdapter
+}
+
+// NewErrPersistence constructs a new error based on the given values
+func NewErrPersistence(operation, entityType string, ID uint32, fields log.Fields, wrapped error) LoggableError {
+	return &ErrPersistence{
+		ErrAdapter{
+			name: "unable-to-persist",
+			fields: merge(fields, log.Fields{
+				"operation":   operation,
+				"entity-type": entityType,
+				"id":          fmt.Sprintf("0x%x", ID)}),
+			wrapped: wrapped,
+		},
+	}
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrPersistence) Log() error {
+	_ = e.ErrAdapter.Log()
+	return e
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrPersistence) LogAt(level log.LogLevel) error {
+	_ = e.ErrAdapter.LogAt(level)
+	return e
+}
+
+// ErrCommunication representation an error condition when an interprocess
+// message communication fails
+type ErrCommunication struct {
+	ErrAdapter
+}
+
+// NewErrCommunication constructs a new error based on the given values
+func NewErrCommunication(operation string, fields log.Fields, wrapped error) LoggableError {
+	return &ErrCommunication{
+		ErrAdapter{
+			name: "failed-communication",
+			fields: merge(fields, log.Fields{
+				"operation": operation}),
+			wrapped: wrapped,
+		},
+	}
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrCommunication) Log() error {
+	_ = e.ErrAdapter.Log()
+	return e
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrCommunication) LogAt(level log.LogLevel) error {
+	_ = e.ErrAdapter.LogAt(level)
+	return e
+}
+
+// ErrFlowOp represents an error condition when a flow operation to a device did
+// not succeed
+type ErrFlowOp struct {
+	ErrAdapter
+}
+
+// NewErrFlowOp constructs a new error based on the given values
+func NewErrFlowOp(operation string, ID uint32, fields log.Fields, wrapped error) LoggableError {
+	return &ErrPersistence{
+		ErrAdapter{
+			name: "unable-to-perform-flow-operation",
+			fields: merge(fields, log.Fields{
+				"operation": operation,
+				"id":        fmt.Sprintf("0x%x", ID)}),
+			wrapped: wrapped,
+		},
+	}
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrFlowOp) Log() error {
+	_ = e.ErrAdapter.Log()
+	return e
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrFlowOp) LogAt(level log.LogLevel) error {
+	_ = e.ErrAdapter.LogAt(level)
+	return e
+}
+
+// ErrTimeout represents an error condition when the deadline for performing an
+// operation has been exceeded
+type ErrTimeout struct {
+	ErrAdapter
+}
+
+// NewErrTimeout constructs a new error based on the given values
+func NewErrTimeout(operation string, fields log.Fields, wrapped error) LoggableError {
+	return &ErrTimeout{
+		ErrAdapter{
+			name:    "operation-timed-out",
+			fields:  merge(fields, log.Fields{"operation": operation}),
+			wrapped: wrapped,
+		},
+	}
+}
+
+// Log logs the error at the default level for log and return
+func (e *ErrTimeout) Log() error {
+	_ = e.ErrAdapter.Log()
+	return e
+}
+
+// LogAt logs the error at the specified level and then returns the error
+func (e *ErrTimeout) LogAt(level log.LogLevel) error {
+	_ = e.ErrAdapter.LogAt(level)
+	return e
+}
+
+var (
+	// ErrNotImplemented error returned when an unimplemented method is
+	// invoked
+	ErrNotImplemented = NewErrAdapter("not-implemented", nil, nil)
+
+	// ErrInvalidPortRange error returned when a given port is not in the
+	// valid range
+	ErrInvalidPortRange = NewErrAdapter("invalid-port-range", nil, nil)
+
+	// ErrStateTransition error returned when a state transition is fails
+	ErrStateTransition = NewErrAdapter("state-transition", nil, nil)
+
+	// ErrResourceManagerInstantiating error returned when an unexpected
+	// condition occcurs while instantiating the resource manager
+	ErrResourceManagerInstantiating = NewErrAdapter("resoure-manager-instantiating", nil, nil)
+)
diff --git a/internal/pkg/core/olt_platform.go b/internal/pkg/core/olt_platform.go
new file mode 100644
index 0000000..747cccf
--- /dev/null
+++ b/internal/pkg/core/olt_platform.go
@@ -0,0 +1,276 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+/*=====================================================================
+
+@TODO: Looks like this Flow id concept below is not used anywhere
+       Propose to remove the below documentation of Flow Id on confirmation
+       of the same
+
+Flow id
+
+    Identifies a flow within a single OLT
+    Flow Id is unique per OLT
+    Multiple GEM ports can map to same flow id
+
+     13    11              4      0
+    +--------+--------------+------+
+    | pon id |    onu id    | Flow |
+    |        |              | idx  |
+    +--------+--------------+------+
+
+    14 bits = 16384 flows (per OLT).
+
+    pon id = 4 bits = 16 PON ports
+    onu id = 7 bits = 128 ONUss per PON port
+    Flow index = 3 bits = 4 bi-directional flows per ONU
+                        = 8 uni-directional flows per ONU
+
+
+Logical (OF) UNI port number
+
+    OpenFlow port number corresponding to PON UNI
+
+     20        12              4      0
+    +--+--------+--------------+------+
+    |0 | pon id |    onu id    |uni id|
+    +--+--------+--------------+------+
+
+    pon id = 8 bits = 256 PON ports
+    onu id = 8 bits = 256 ONUs per PON port
+
+Logical (OF) NNI port number
+
+    OpenFlow port number corresponding to PON NNI
+
+     20                             0
+    +--+----------------------------+
+    |1 |                    intf_id |
+    +--+----------------------------+
+
+    No overlap with UNI port number space
+
+
+PON OLT (OF) port number
+
+    OpenFlow port number corresponding to PON OLT ports
+
+     31     28                                 0
+    +--------+------------------------~~~------+
+    |  0x2   |          pon intf id            |
+    +--------+------------------------~~~------+
+*/
+
+const (
+	// Number of bits for the physical UNI of the ONUs
+	bitsForUniID = 4
+	// Number of bits for the ONU ID
+	bitsForONUID = 8
+	// Number of bits for PON ID
+	bitsForPONID = 8
+	// Number of bits to differentiate between UNI and NNI Logical Port
+	bitsForUNINNIDiff = 1
+	//MaxOnusPerPon is Max number of ONUs on any PON port
+	MaxOnusPerPon = (1 << bitsForONUID)
+	//MaxPonsPerOlt is Max number of PON ports on any OLT
+	MaxPonsPerOlt = (1 << bitsForPONID)
+	//MaxUnisPerOnu is the Max number of UNI ports on any ONU
+	MaxUnisPerOnu = (1 << bitsForUniID)
+	//Bit position where the differentiation bit is located
+	nniUniDiffPos = (bitsForUniID + bitsForONUID + bitsForPONID)
+	//Bit position where the marker for PON port type of OF port is present
+	ponIntfMarkerPos = 28
+	//Value of marker used to distinguish PON port type of OF port
+	ponIntfMarkerValue = 0x2
+	// Number of bits for NNI ID
+	bitsforNNIID = 20
+	// minNniIntPortNum is used to store start range of nni port number (1 << 20) 1048576
+	minNniIntPortNum = (1 << bitsforNNIID)
+	// maxNniPortNum is used to store the maximum range of nni port number ((1 << 21)-1) 2097151
+	maxNniPortNum = ((1 << (bitsforNNIID + 1)) - 1)
+)
+
+//MinUpstreamPortID value
+var MinUpstreamPortID = 0xfffd
+
+//MaxUpstreamPortID value
+var MaxUpstreamPortID = 0xfffffffd
+
+var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
+
+//MkUniPortNum returns new UNIportNum based on intfID, inuID and uniID
+func MkUniPortNum(intfID, onuID, uniID uint32) uint32 {
+	var limit = int(onuID)
+	if limit > MaxOnusPerPon {
+		log.Warn("Warning: exceeded the MAX ONUS per PON")
+	}
+	return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
+}
+
+//OnuIDFromPortNum returns ONUID derived from portNumber
+func OnuIDFromPortNum(portNum uint32) uint32 {
+	return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
+}
+
+//IntfIDFromUniPortNum returns IntfID derived from portNum
+func IntfIDFromUniPortNum(portNum uint32) uint32 {
+	return (portNum >> (bitsForUniID + bitsForONUID)) & (MaxPonsPerOlt - 1)
+}
+
+//UniIDFromPortNum return UniID derived from portNum
+func UniIDFromPortNum(portNum uint32) uint32 {
+	return (portNum) & (MaxUnisPerOnu - 1)
+}
+
+//IntfIDToPortNo returns portId derived from intftype, intfId and portType
+func IntfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
+	if (intfType) == voltha.Port_ETHERNET_NNI {
+		return (1 << nniUniDiffPos) | intfID
+	}
+	if (intfType) == voltha.Port_PON_OLT {
+		return (ponIntfMarkerValue << ponIntfMarkerPos) | intfID
+	}
+	return 0
+}
+
+//PortNoToIntfID returns portnumber derived from interfaceID
+func PortNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
+	if (intfType) == voltha.Port_ETHERNET_NNI {
+		return (1 << nniUniDiffPos) ^ portno
+	}
+	if (intfType) == voltha.Port_PON_OLT {
+		return (ponIntfMarkerValue << ponIntfMarkerPos) ^ portno
+	}
+	return 0
+}
+
+//IntfIDFromNniPortNum returns Intf ID derived from portNum
+func IntfIDFromNniPortNum(portNum uint32) (uint32, error) {
+	if portNum < minNniIntPortNum || portNum > maxNniPortNum {
+		log.Errorw("NNIPortNumber is not in valid range", log.Fields{"portNum": portNum})
+		return uint32(0), ErrInvalidPortRange
+	}
+	return (portNum & 0xFFFF), nil
+}
+
+//IntfIDToPortTypeName returns port type derived from the intfId
+func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
+	if ((ponIntfMarkerValue << ponIntfMarkerPos) ^ intfID) < MaxPonsPerOlt {
+		return voltha.Port_PON_OLT
+	}
+	if (intfID & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos) {
+		return voltha.Port_ETHERNET_NNI
+	}
+	return voltha.Port_ETHERNET_UNI
+}
+
+//ExtractAccessFromFlow returns AccessDevice information
+func ExtractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
+	if IsUpstream(outPort) {
+		return inPort, IntfIDFromUniPortNum(inPort), OnuIDFromPortNum(inPort), UniIDFromPortNum(inPort)
+	}
+	return outPort, IntfIDFromUniPortNum(outPort), OnuIDFromPortNum(outPort), UniIDFromPortNum(outPort)
+}
+
+//IsUpstream returns true for Upstream and false for downstream
+func IsUpstream(outPort uint32) bool {
+	for _, port := range controllerPorts {
+		if port == outPort {
+			return true
+		}
+	}
+	return (outPort & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos)
+}
+
+//IsControllerBoundFlow returns true/false
+func IsControllerBoundFlow(outPort uint32) bool {
+	for _, port := range controllerPorts {
+		if port == outPort {
+			return true
+		}
+	}
+	return false
+}
+
+//OnuIDFromUniPortNum returns onuId from give portNum information.
+func OnuIDFromUniPortNum(portNum uint32) uint32 {
+	return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
+}
+
+//FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
+func FlowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
+	var uniPortNo uint32
+	var ponIntf uint32
+	var onuID uint32
+	var uniID uint32
+	var inPort uint32
+	var ethType uint32
+
+	if flowDirection == "upstream" {
+		if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
+			for _, field := range flows.GetOfbFields(flow) {
+				if field.GetType() == flows.IN_PORT {
+					uniPortNo = field.GetPort()
+					break
+				}
+			}
+		}
+	} else if flowDirection == "downstream" {
+		if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
+			for _, field := range flows.GetOfbFields(flow) {
+				if field.GetType() == flows.METADATA {
+					for _, action := range flows.GetActions(flow) {
+						if action.Type == flows.OUTPUT {
+							if out := action.GetOutput(); out != nil {
+								uniPortNo = out.GetPort()
+							}
+							break
+						}
+					}
+				} else if field.GetType() == flows.IN_PORT {
+					inPort = field.GetPort()
+				} else if field.GetType() == flows.ETH_TYPE {
+					ethType = field.GetEthType()
+				}
+			}
+		}
+	}
+
+	if uniPortNo == 0 {
+		return 0, 0, 0, 0, 0, 0, NewErrNotFound("pon-interface", log.Fields{
+			"flow-direction": flowDirection}, nil)
+	}
+
+	ponIntf = IntfIDFromUniPortNum(uniPortNo)
+	onuID = OnuIDFromUniPortNum(uniPortNo)
+	uniID = UniIDFromPortNum(uniPortNo)
+
+	log.Debugw("flow extract info result",
+		log.Fields{"uniPortNo": uniPortNo, "ponIntf": ponIntf,
+			"onuID": onuID, "uniID": uniID, "inPort": inPort, "ethType": ethType})
+
+	return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
+}
diff --git a/internal/pkg/core/olt_platform_test.go b/internal/pkg/core/olt_platform_test.go
new file mode 100644
index 0000000..4f3d5bf
--- /dev/null
+++ b/internal/pkg/core/olt_platform_test.go
@@ -0,0 +1,383 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"math"
+	"reflect"
+	"testing"
+
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+func TestMkUniPortNum(t *testing.T) {
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"MkUniPortNum-1", args{1, 1, 1}, ((1 * 4096) + (1 * 16) + 1)},
+		{"MkUniPortNum-2", args{4, 5, 6}, ((4 * 4096) + (5 * 16) + 6)},
+		// Negative test cases to cover the log.warn
+		{"MkUniPortNum-3", args{4, 130, 6}, ((4 * 4096) + (130 * 16) + 6)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MkUniPortNum(tt.args.intfID, tt.args.onuID, tt.args.uniID); got != tt.want {
+				t.Errorf("MkUniPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestOnuIDFromPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"OnuIDFromPortNum-1", args{portNum: 8096}, ((8096 / 16) & 255)},
+		{"OnuIDFromPortNum-2", args{portNum: 9095}, ((9095 / 16) & 255)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := OnuIDFromPortNum(tt.args.portNum); got != tt.want {
+				t.Errorf("OnuIDFromPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestIntfIDFromUniPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"IntfIDFromUniPortNum-1", args{portNum: 8096}, ((8096 / 4096) & 15)},
+		// Negative Testcase
+		{"IntfIDFromUniPortNum-2", args{portNum: 1024}, ((1024 / 4096) & 15)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IntfIDFromUniPortNum(tt.args.portNum); got != tt.want {
+				t.Errorf("IntfIDFromUniPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestUniIDFromPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+
+		// TODO: Add test cases.
+		{"UniIDFromPortNum-1", args{portNum: 8096}, (8096 & 15)},
+		{"UniIDFromPortNum-2", args{portNum: 1024}, (1024 & 15)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := UniIDFromPortNum(tt.args.portNum); got != tt.want {
+				t.Errorf("UniIDFromPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestIntfIDToPortNo(t *testing.T) {
+	type args struct {
+		intfID   uint32
+		intfType voltha.Port_PortType
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"IntfIDToPortNo-1", args{intfID: 120, intfType: voltha.Port_ETHERNET_NNI}, (uint32(math.Pow(2, 20)) + 120)},
+		{"IntfIDToPortNo-2", args{intfID: 1024, intfType: voltha.Port_ETHERNET_UNI}, 0},
+		{"IntfIDToPortNo-3", args{intfID: 456, intfType: voltha.Port_PON_OLT}, (uint32(2*math.Pow(2, 28)) + 456)},
+		{"IntfIDToPortNo-4", args{intfID: 28, intfType: voltha.Port_PON_ONU}, 0},
+		{"IntfIDToPortNo-5", args{intfID: 45, intfType: voltha.Port_UNKNOWN}, 0},
+		{"IntfIDToPortNo-6", args{intfID: 45, intfType: voltha.Port_VENET_OLT}, 0},
+		{"IntfIDToPortNo-7", args{intfID: 45, intfType: voltha.Port_VENET_ONU}, 0},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IntfIDToPortNo(tt.args.intfID, tt.args.intfType); got != tt.want {
+				t.Errorf("IntfIDToPortNo() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestIntfIDFromNniPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+
+	tests := []struct {
+		name    string
+		args    args
+		want    uint32
+		wantErr error
+	}{
+		// TODO: Add test cases.
+		{"IntfIDFromNniPortNum-01", args{portNum: 8081}, 0, ErrInvalidPortRange},
+		{"IntfIDFromNniPortNum-02", args{portNum: 9090}, 0, ErrInvalidPortRange},
+		{"IntfIDFromNniPortNum-03", args{portNum: 0}, 0, ErrInvalidPortRange},
+		{"IntfIDFromNniPortNum-04", args{portNum: 65535}, 0, ErrInvalidPortRange},
+		{"IntfIDFromNniPortNum-05", args{portNum: 1048575}, 0, ErrInvalidPortRange},
+		{"IntfIDFromNniPortNum-06", args{portNum: 1048576}, 0, nil},
+		{"IntfIDFromNniPortNum-07", args{portNum: 1048577}, 1, nil},
+		{"IntfIDFromNniPortNum-08", args{portNum: 1048578}, 2, nil},
+		{"IntfIDFromNniPortNum-09", args{portNum: 1048579}, 3, nil},
+		{"IntfIDFromNniPortNum-10", args{portNum: 2097150}, 65534, nil},
+		{"IntfIDFromNniPortNum-11", args{portNum: 2097151}, 65535, nil},
+		{"IntfIDFromNniPortNum-12", args{portNum: 3000000}, 0, ErrInvalidPortRange},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := IntfIDFromNniPortNum(tt.args.portNum)
+			if got != tt.want || err != tt.wantErr {
+				t.Errorf("IntfIDFromNniPortNum(): FOR[%v] WANT[%v and %v] GOT[%v and %v]",
+					tt.args.portNum, tt.want, tt.wantErr, got, err)
+			}
+		})
+	}
+}
+
+func TestIntfIDToPortTypeName(t *testing.T) {
+	type args struct {
+		intfID uint32
+	}
+	var input uint32
+	input = uint32(2*math.Pow(2, 28)) | 3
+	tests := []struct {
+		name string
+		args args
+		want voltha.Port_PortType
+	}{
+		// TODO: Add test cases.
+		{"IntfIDToPortTypeName-1", args{intfID: 1048576}, voltha.Port_ETHERNET_NNI},
+		{"IntfIDToPortTypeName-2", args{intfID: 1000}, voltha.Port_ETHERNET_UNI},
+		{"IntfIDToPortTypeName-2", args{intfID: input}, voltha.Port_PON_OLT},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IntfIDToPortTypeName(tt.args.intfID); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("IntfIDToPortTypeName() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestExtractAccessFromFlow(t *testing.T) {
+	type args struct {
+		inPort  uint32
+		outPort uint32
+	}
+	tests := []struct {
+		name   string
+		args   args
+		port   uint32
+		IntfID uint32
+		onuID  uint32
+		uniID  uint32
+	}{
+		// TODO: Add test cases.
+		{"ExtractAccessFromFlow-1", args{inPort: 100, outPort: 1048576}, 100, 0, 6, 4},
+		{"ExtractAccessFromFlow-2", args{inPort: 1048576, outPort: 10}, 10, 0, 0, 10},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1, got2, got3 := ExtractAccessFromFlow(tt.args.inPort, tt.args.outPort)
+			if got != tt.port {
+				t.Errorf("ExtractAccessFromFlow() got = %v, want %v", got, tt.port)
+			}
+			if got1 != tt.IntfID {
+				t.Errorf("ExtractAccessFromFlow() got1 = %v, want %v", got1, tt.IntfID)
+			}
+			if got2 != tt.onuID {
+				t.Errorf("ExtractAccessFromFlow() got2 = %v, want %v", got2, tt.onuID)
+			}
+			if got3 != tt.uniID {
+				t.Errorf("ExtractAccessFromFlow() got3 = %v, want %v", got3, tt.uniID)
+			}
+		})
+	}
+	//t.Error()
+}
+
+func TestIsUpstream(t *testing.T) {
+	type args struct {
+		outPort uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		// TODO: Add test cases.
+		{"TestIsUpstream-1", args{outPort: 65533}, true},
+		{"TestIsUpstream-2", args{outPort: 1048576}, true},
+		{"TestIsUpstream-3", args{outPort: 1048577}, true},
+		{"TestIsUpstream-4", args{outPort: 1048578}, true},
+		{"TestIsUpstream-6", args{outPort: 1000}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsUpstream(tt.args.outPort); got != tt.want {
+				t.Errorf("IsUpstream() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsControllerBoundFlow(t *testing.T) {
+	type args struct {
+		outPort uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		// TODO: Add test cases.
+		{"IsControllerBoundFlow-1", args{outPort: 65533}, true},
+		{"IsControllerBoundFlow-2", args{outPort: 65536}, false},
+		{"IsControllerBoundFlow-3", args{outPort: 65537}, false},
+		{"IsControllerBoundFlow-4", args{outPort: 65538}, false},
+		{"IsControllerBoundFlow-5", args{outPort: 65539}, false},
+		{"IsControllerBoundFlow-6", args{outPort: 1000}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsControllerBoundFlow(tt.args.outPort); got != tt.want {
+				t.Errorf("IsControllerBoundFlow() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestFlowExtractInfo(t *testing.T) {
+	fa := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(2),
+			fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2)),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+			fu.EthType(2048),
+		},
+
+		Actions: []*ofp.OfpAction{
+			fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+			fu.Output(1),
+		},
+	}
+	ofpstats := fu.MkFlowStat(fa)
+	type args struct {
+		flow          *ofp.OfpFlowStats
+		flowDirection string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    uint32
+		want1   uint32
+		want2   uint32
+		want3   uint32
+		want4   uint32
+		want5   uint32
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"FlowExtractInfo-1", args{flow: ofpstats, flowDirection: "upstream"}, 2, 0, 0, 2, 0, 0, false},
+
+		// Negative Testcases
+		{"FlowExtractInfo-2", args{flow: ofpstats, flowDirection: "downstream"}, 1, 0, 0, 1, 2, 2048, false},
+		{"FlowExtractInfo-3", args{flow: nil, flowDirection: "downstream"}, 0, 0, 0, 0, 0, 0, true},
+		{"FlowExtractInfo-4", args{flow: &ofp.OfpFlowStats{}, flowDirection: "downstream"}, 0, 0, 0, 0, 0, 0, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1, got2, got3, got4, got5, err := FlowExtractInfo(tt.args.flow, tt.args.flowDirection)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("FlowExtractInfo() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("FlowExtractInfo() got = %v, want %v", got, tt.want)
+				return
+			}
+			if got1 != tt.want1 {
+				t.Errorf("FlowExtractInfo() got1 = %v, want %v", got1, tt.want1)
+				return
+			}
+			if got2 != tt.want2 {
+				t.Errorf("FlowExtractInfo() got2 = %v, want %v", got2, tt.want2)
+				return
+			}
+			if got3 != tt.want3 {
+				t.Errorf("FlowExtractInfo() got3 = %v, want %v", got3, tt.want3)
+				return
+			}
+			if got4 != tt.want4 {
+				t.Errorf("FlowExtractInfo() got4 = %v, want %v", got4, tt.want4)
+				return
+			}
+			if got5 != tt.want5 {
+				t.Errorf("FlowExtractInfo() got5 = %v, want %v", got5, tt.want5)
+				return
+			}
+		})
+	}
+}
diff --git a/internal/pkg/core/olt_state_transitions.go b/internal/pkg/core/olt_state_transitions.go
new file mode 100644
index 0000000..c10d17d
--- /dev/null
+++ b/internal/pkg/core/olt_state_transitions.go
@@ -0,0 +1,187 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"reflect"
+	"runtime"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+// DeviceState OLT Device state
+type DeviceState int
+
+const (
+	// deviceStateNull OLT is not instantiated
+	deviceStateNull DeviceState = iota
+	// deviceStateInit OLT is instantiated
+	deviceStateInit
+	// deviceStateConnected Grpc session established with OLT
+	deviceStateConnected
+	// deviceStateUp Admin state of OLT is UP
+	deviceStateUp
+	// deviceStateDown Admin state of OLT is down
+	deviceStateDown
+)
+
+// Trigger for changing the state
+type Trigger int
+
+const (
+	// DeviceInit Go to Device init state
+	DeviceInit Trigger = iota
+	// GrpcConnected Go to connected state
+	GrpcConnected
+	// DeviceUpInd Go to Device up state
+	DeviceUpInd
+	// DeviceDownInd Go to Device down state
+	DeviceDownInd
+	// GrpcDisconnected Go to Device init state
+	GrpcDisconnected
+)
+
+// TransitionHandler function type for handling transition
+type TransitionHandler func(ctx context.Context) error
+
+// Transition to store state machine
+type Transition struct {
+	previousState []DeviceState
+	currentState  DeviceState
+	before        []TransitionHandler
+	after         []TransitionHandler
+}
+
+// TransitionMap to store all the states and current device state
+type TransitionMap struct {
+	transitions        map[Trigger]Transition
+	currentDeviceState DeviceState
+}
+
+//    OpenoltDevice state machine:
+//
+//        null ----> init ------> connected -----> up -----> down
+//                   ^ ^             |             ^         | |
+//                   | |             |             |         | |
+//                   | +-------------+             +---------+ |
+//                   |                                         |
+//                   +-----------------------------------------+
+
+// NewTransitionMap create a new state machine with all the transitions
+func NewTransitionMap(dh *DeviceHandler) *TransitionMap {
+	var transitionMap TransitionMap
+	transitionMap.currentDeviceState = deviceStateNull
+	transitionMap.transitions = make(map[Trigger]Transition)
+	// In doInit establish the grpc session
+	transitionMap.transitions[DeviceInit] =
+		Transition{
+			previousState: []DeviceState{deviceStateNull, deviceStateDown},
+			currentState:  deviceStateInit,
+			before:        []TransitionHandler{dh.doStateInit},
+			after:         []TransitionHandler{dh.postInit}}
+	// If gRpc session fails, re-establish the grpc session
+	transitionMap.transitions[GrpcDisconnected] =
+		Transition{
+			previousState: []DeviceState{deviceStateConnected, deviceStateDown},
+			currentState:  deviceStateInit,
+			before:        []TransitionHandler{dh.doStateInit},
+			after:         []TransitionHandler{dh.postInit}}
+	// in doConnected, create logical device and read the indications
+	transitionMap.transitions[GrpcConnected] =
+		Transition{
+			previousState: []DeviceState{deviceStateInit},
+			currentState:  deviceStateConnected,
+			before:        []TransitionHandler{dh.doStateConnected}}
+
+	// Once the olt UP is indication received, then do state up
+	transitionMap.transitions[DeviceUpInd] =
+		Transition{
+			previousState: []DeviceState{deviceStateConnected, deviceStateDown},
+			currentState:  deviceStateUp,
+			before:        []TransitionHandler{dh.doStateUp}}
+	// If olt DOWN indication comes then do sate down
+	transitionMap.transitions[DeviceDownInd] =
+		Transition{
+			previousState: []DeviceState{deviceStateUp},
+			currentState:  deviceStateDown,
+			before:        []TransitionHandler{dh.doStateDown}}
+
+	return &transitionMap
+}
+
+// funcName gets the handler function name
+func funcName(f interface{}) string {
+	p := reflect.ValueOf(f).Pointer()
+	rf := runtime.FuncForPC(p)
+	return rf.Name()
+}
+
+// isValidTransition checks for the new state transition is valid from current state
+func (tMap *TransitionMap) isValidTransition(trigger Trigger) bool {
+	// Validate the state transition
+	for _, state := range tMap.transitions[trigger].previousState {
+		if tMap.currentDeviceState == state {
+			return true
+		}
+	}
+	return false
+}
+
+// Handle moves the state machine to next state based on the trigger and invokes the before and
+// after handlers if the transition is a valid transition
+func (tMap *TransitionMap) Handle(ctx context.Context, trigger Trigger) {
+
+	// Check whether the transtion is valid from current state
+	if !tMap.isValidTransition(trigger) {
+		log.Errorw("Invalid transition triggered ", log.Fields{"CurrentState": tMap.currentDeviceState, "Trigger": trigger})
+		return
+	}
+
+	// Invoke the before handlers
+	beforeHandlers := tMap.transitions[trigger].before
+	if beforeHandlers == nil {
+		log.Debugw("No handlers for before", log.Fields{"trigger": trigger})
+	}
+	for _, handler := range beforeHandlers {
+		log.Debugw("running-before-handler", log.Fields{"handler": funcName(handler)})
+		if err := handler(ctx); err != nil {
+			// TODO handle error
+			log.Error(err)
+			return
+		}
+	}
+
+	// Update the state
+	tMap.currentDeviceState = tMap.transitions[trigger].currentState
+	log.Debugw("Updated device state ", log.Fields{"CurrentDeviceState": tMap.currentDeviceState})
+
+	// Invoke the after handlers
+	afterHandlers := tMap.transitions[trigger].after
+	if afterHandlers == nil {
+		log.Debugw("No handlers for after", log.Fields{"trigger": trigger})
+	}
+	for _, handler := range afterHandlers {
+		log.Debugw("running-after-handler", log.Fields{"handler": funcName(handler)})
+		if err := handler(ctx); err != nil {
+			// TODO handle error
+			log.Error(err)
+			return
+		}
+	}
+}
diff --git a/internal/pkg/core/olt_state_transitions_test.go b/internal/pkg/core/olt_state_transitions_test.go
new file mode 100644
index 0000000..75e7807
--- /dev/null
+++ b/internal/pkg/core/olt_state_transitions_test.go
@@ -0,0 +1,188 @@
+/*
+ * 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 core
+
+import (
+	"context"
+	"reflect"
+	"testing"
+	"time"
+)
+
+/**
+Get's the transition Map with current state of the device.
+*/
+func getTranisitions() map[Trigger]Transition {
+	transitions := make(map[Trigger]Transition)
+	transition := Transition{
+		previousState: []DeviceState{deviceStateConnected},
+		currentState:  deviceStateConnected,
+	}
+	transitions[DeviceInit] = transition
+	return transitions
+}
+
+/**
+Get's the transition Map with after Transition func added.
+*/
+func getTranisitionsAfter() map[Trigger]Transition {
+	transitions := make(map[Trigger]Transition)
+	transition := Transition{
+		previousState: []DeviceState{deviceStateConnected},
+		currentState:  deviceStateConnected,
+		after: []TransitionHandler{func(ctx context.Context) error {
+			return nil
+		}, func(ctx context.Context) error {
+			return ErrStateTransition
+		}},
+	}
+	transitions[GrpcConnected] = transition
+	return transitions
+}
+
+/**
+Get's the transition Map with before Transition func added.
+*/
+func getTranisitionsBefore() map[Trigger]Transition {
+	transitions := make(map[Trigger]Transition)
+	transition := Transition{
+		previousState: []DeviceState{deviceStateConnected},
+		currentState:  deviceStateConnected,
+		before: []TransitionHandler{func(ctx context.Context) error {
+			return nil
+		}, func(ctx context.Context) error {
+			return ErrStateTransition
+		}},
+	}
+	transitions[GrpcConnected] = transition
+	return transitions
+}
+
+/**
+Check's Creation of transition Map, return's NewTransitionMap.
+*/
+func TestNewTransitionMap(t *testing.T) {
+	type args struct {
+		dh *DeviceHandler
+	}
+	tests := []struct {
+		name string
+		args args
+		want *TransitionMap
+	}{
+		{"NewTransitionMap-1", args{newMockDeviceHandler()}, &TransitionMap{}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NewTransitionMap(tt.args.dh); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("NewTransitionMap() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+/**
+Checks the different transition of the device handled properly.
+*/
+func TestTransitionMap_Handle(t *testing.T) {
+	type fields struct {
+		transitions        map[Trigger]Transition
+		currentDeviceState DeviceState
+	}
+	type args struct {
+		trigger Trigger
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		{"Handle-1", fields{getTranisitions(), deviceStateDown}, args{GrpcConnected}},
+		{"Handle-2", fields{getTranisitions(), deviceStateConnected}, args{GrpcConnected}},
+		{"Handle-3", fields{getTranisitionsBefore(), deviceStateConnected}, args{GrpcConnected}},
+		{"Handle-4", fields{getTranisitionsAfter(), deviceStateConnected}, args{GrpcConnected}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tMap := &TransitionMap{
+				transitions:        tt.fields.transitions,
+				currentDeviceState: tt.fields.currentDeviceState,
+			}
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			tMap.Handle(ctx, tt.args.trigger)
+		})
+	}
+}
+
+/**
+Check's if the transition is valid or not.
+*/
+func TestTransitionMap_isValidTransition(t *testing.T) {
+	type fields struct {
+		transitions        map[Trigger]Transition
+		currentDeviceState DeviceState
+	}
+	type args struct {
+		trigger Trigger
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   bool
+	}{
+		{"isValidTransition-1", fields{getTranisitions(), deviceStateConnected}, args{DeviceInit},
+			true},
+		{"isValidTransition-2", fields{getTranisitions(), deviceStateDown}, args{GrpcConnected},
+			false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tMap := &TransitionMap{
+				transitions:        tt.fields.transitions,
+				currentDeviceState: tt.fields.currentDeviceState,
+			}
+			if got := tMap.isValidTransition(tt.args.trigger); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("isValidTransition() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+/**
+Get's the After/Before transition method's function name.
+*/
+func Test_funcName(t *testing.T) {
+	type args struct {
+		f interface{}
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{"FuncName-1", args{newMockDeviceHandler()}, ""},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := funcName(tt.args.f); got != tt.want {
+				t.Errorf("funcName() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/core/openolt.go b/internal/pkg/core/openolt.go
new file mode 100644
index 0000000..9a5167f
--- /dev/null
+++ b/internal/pkg/core/openolt.go
@@ -0,0 +1,388 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"sync"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-openolt-adapter/internal/pkg/config"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	"github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+//OpenOLT structure holds the OLT information
+type OpenOLT struct {
+	deviceHandlers              map[string]*DeviceHandler
+	coreProxy                   adapterif.CoreProxy
+	adapterProxy                adapterif.AdapterProxy
+	eventProxy                  adapterif.EventProxy
+	kafkaICProxy                kafka.InterContainerProxy
+	config                      *config.AdapterFlags
+	numOnus                     int
+	KVStoreHost                 string
+	KVStorePort                 int
+	KVStoreType                 string
+	exitChannel                 chan int
+	HeartbeatCheckInterval      time.Duration
+	HeartbeatFailReportInterval time.Duration
+	GrpcTimeoutInterval         time.Duration
+	lockDeviceHandlersMap       sync.RWMutex
+}
+
+//NewOpenOLT returns a new instance of OpenOLT
+func NewOpenOLT(ctx context.Context, kafkaICProxy kafka.InterContainerProxy,
+	coreProxy adapterif.CoreProxy, adapterProxy adapterif.AdapterProxy,
+	eventProxy adapterif.EventProxy, cfg *config.AdapterFlags) *OpenOLT {
+	var openOLT OpenOLT
+	openOLT.exitChannel = make(chan int, 1)
+	openOLT.deviceHandlers = make(map[string]*DeviceHandler)
+	openOLT.kafkaICProxy = kafkaICProxy
+	openOLT.config = cfg
+	openOLT.numOnus = cfg.OnuNumber
+	openOLT.coreProxy = coreProxy
+	openOLT.adapterProxy = adapterProxy
+	openOLT.eventProxy = eventProxy
+	openOLT.KVStoreHost = cfg.KVStoreHost
+	openOLT.KVStorePort = cfg.KVStorePort
+	openOLT.KVStoreType = cfg.KVStoreType
+	openOLT.HeartbeatCheckInterval = cfg.HeartbeatCheckInterval
+	openOLT.HeartbeatFailReportInterval = cfg.HeartbeatFailReportInterval
+	openOLT.GrpcTimeoutInterval = cfg.GrpcTimeoutInterval
+	openOLT.lockDeviceHandlersMap = sync.RWMutex{}
+	return &openOLT
+}
+
+//Start starts (logs) the device manager
+func (oo *OpenOLT) Start(ctx context.Context) error {
+	log.Info("starting-device-manager")
+	log.Info("device-manager-started")
+	return nil
+}
+
+//Stop terminates the session
+func (oo *OpenOLT) Stop(ctx context.Context) error {
+	log.Info("stopping-device-manager")
+	oo.exitChannel <- 1
+	log.Info("device-manager-stopped")
+	return nil
+}
+
+func sendResponse(ctx context.Context, ch chan interface{}, result interface{}) {
+	if ctx.Err() == nil {
+		// Returned response only of the ctx has not been canceled/timeout/etc
+		// Channel is automatically closed when a context is Done
+		ch <- result
+		log.Debugw("sendResponse", log.Fields{"result": result})
+	} else {
+		// Should the transaction be reverted back?
+		log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
+	}
+}
+
+func (oo *OpenOLT) addDeviceHandlerToMap(agent *DeviceHandler) {
+	oo.lockDeviceHandlersMap.Lock()
+	defer oo.lockDeviceHandlersMap.Unlock()
+	if _, exist := oo.deviceHandlers[agent.deviceID]; !exist {
+		oo.deviceHandlers[agent.deviceID] = agent
+	}
+}
+
+func (oo *OpenOLT) deleteDeviceHandlerToMap(agent *DeviceHandler) {
+	oo.lockDeviceHandlersMap.Lock()
+	defer oo.lockDeviceHandlersMap.Unlock()
+	delete(oo.deviceHandlers, agent.deviceID)
+}
+
+func (oo *OpenOLT) getDeviceHandler(deviceID string) *DeviceHandler {
+	oo.lockDeviceHandlersMap.Lock()
+	defer oo.lockDeviceHandlersMap.Unlock()
+	if agent, ok := oo.deviceHandlers[deviceID]; ok {
+		return agent
+	}
+	return nil
+}
+
+//createDeviceTopic returns
+func (oo *OpenOLT) createDeviceTopic(device *voltha.Device) error {
+	log.Infow("create-device-topic", log.Fields{"deviceId": device.Id})
+	defaultTopic := oo.kafkaICProxy.GetDefaultTopic()
+	deviceTopic := kafka.Topic{Name: defaultTopic.Name + "_" + device.Id}
+	// TODO for the offset
+	if err := oo.kafkaICProxy.SubscribeWithDefaultRequestHandler(deviceTopic, 0); err != nil {
+		log.Infow("create-device-topic-failed", log.Fields{"deviceId": device.Id, "error": err})
+		return err
+	}
+	return nil
+}
+
+// Adopt_device creates a new device handler if not present already and then adopts the device
+func (oo *OpenOLT) Adopt_device(device *voltha.Device) error {
+	ctx := context.Background()
+	if device == nil {
+		return NewErrInvalidValue(log.Fields{"device": nil}, nil).Log()
+	}
+	log.Infow("adopt-device", log.Fields{"deviceId": device.Id})
+	var handler *DeviceHandler
+	if handler = oo.getDeviceHandler(device.Id); handler == nil {
+		handler := NewDeviceHandler(oo.coreProxy, oo.adapterProxy, oo.eventProxy, device, oo)
+		oo.addDeviceHandlerToMap(handler)
+		go handler.AdoptDevice(ctx, device)
+		// Launch the creation of the device topic
+		// go oo.createDeviceTopic(device)
+	}
+	return nil
+}
+
+//Get_ofp_device_info returns OFP information for the given device
+func (oo *OpenOLT) Get_ofp_device_info(device *voltha.Device) (*ic.SwitchCapability, error) {
+	log.Infow("Get_ofp_device_info", log.Fields{"deviceId": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		return handler.GetOfpDeviceInfo(device)
+	}
+	return nil, NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Get_ofp_port_info returns OFP port information for the given device
+func (oo *OpenOLT) Get_ofp_port_info(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
+	log.Infow("Get_ofp_port_info", log.Fields{"deviceId": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		return handler.GetOfpPortInfo(device, portNo)
+	}
+	return nil, NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Process_inter_adapter_message sends messages to a target device (between adapters)
+func (oo *OpenOLT) Process_inter_adapter_message(msg *ic.InterAdapterMessage) error {
+	log.Infow("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id})
+	targetDevice := msg.Header.ProxyDeviceId // Request?
+	if targetDevice == "" && msg.Header.ToDeviceId != "" {
+		// Typical response
+		targetDevice = msg.Header.ToDeviceId
+	}
+	if handler := oo.getDeviceHandler(targetDevice); handler != nil {
+		return handler.ProcessInterAdapterMessage(msg)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": targetDevice}, nil).Log()
+}
+
+//Adapter_descriptor not implemented
+func (oo *OpenOLT) Adapter_descriptor() error {
+	return ErrNotImplemented
+}
+
+//Device_types unimplemented
+func (oo *OpenOLT) Device_types() (*voltha.DeviceTypes, error) {
+	return nil, ErrNotImplemented
+}
+
+//Health  returns unimplemented
+func (oo *OpenOLT) Health() (*voltha.HealthStatus, error) {
+	return nil, ErrNotImplemented
+}
+
+//Reconcile_device unimplemented
+func (oo *OpenOLT) Reconcile_device(device *voltha.Device) error {
+	ctx := context.Background()
+	if device == nil {
+		return NewErrInvalidValue(log.Fields{"device": nil}, nil).Log()
+	}
+	log.Infow("reconcile-device", log.Fields{"deviceId": device.Id})
+	var handler *DeviceHandler
+	if handler = oo.getDeviceHandler(device.Id); handler == nil {
+		handler := NewDeviceHandler(oo.coreProxy, oo.adapterProxy, oo.eventProxy, device, oo)
+		oo.addDeviceHandlerToMap(handler)
+		handler.transitionMap = NewTransitionMap(handler)
+		handler.transitionMap.Handle(ctx, DeviceInit)
+	}
+	return nil
+}
+
+//Abandon_device unimplemented
+func (oo *OpenOLT) Abandon_device(device *voltha.Device) error {
+	return ErrNotImplemented
+}
+
+//Disable_device disables the given device
+func (oo *OpenOLT) Disable_device(device *voltha.Device) error {
+	log.Infow("disable-device", log.Fields{"deviceId": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		return handler.DisableDevice(device)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Reenable_device enables the olt device after disable
+func (oo *OpenOLT) Reenable_device(device *voltha.Device) error {
+	log.Infow("reenable-device", log.Fields{"deviceId": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		return handler.ReenableDevice(device)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Reboot_device reboots the given device
+func (oo *OpenOLT) Reboot_device(device *voltha.Device) error {
+	log.Infow("reboot-device", log.Fields{"deviceId": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		return handler.RebootDevice(device)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Self_test_device unimplented
+func (oo *OpenOLT) Self_test_device(device *voltha.Device) error {
+	return ErrNotImplemented
+}
+
+//Delete_device unimplemented
+func (oo *OpenOLT) Delete_device(device *voltha.Device) error {
+	log.Infow("delete-device", log.Fields{"deviceId": device.Id})
+	ctx := context.Background()
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		if err := handler.DeleteDevice(ctx, device); err != nil {
+			log.Errorw("failed-to-handle-delete-device", log.Fields{"device-id": device.Id})
+		}
+		oo.deleteDeviceHandlerToMap(handler)
+		return nil
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Get_device_details unimplemented
+func (oo *OpenOLT) Get_device_details(device *voltha.Device) error {
+	return ErrNotImplemented
+}
+
+//Update_flows_bulk returns
+func (oo *OpenOLT) Update_flows_bulk(device *voltha.Device, flows *voltha.Flows, groups *voltha.FlowGroups, flowMetadata *voltha.FlowMetadata) error {
+	return ErrNotImplemented
+}
+
+//Update_flows_incrementally updates (add/remove) the flows on a given device
+func (oo *OpenOLT) Update_flows_incrementally(device *voltha.Device, flows *openflow_13.FlowChanges, groups *openflow_13.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
+	log.Debugw("Update_flows_incrementally", log.Fields{"deviceId": device.Id, "flows": flows, "flowMetadata": flowMetadata})
+	ctx := context.Background()
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		return handler.UpdateFlowsIncrementally(ctx, device, flows, groups, flowMetadata)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil).Log()
+}
+
+//Update_pm_config returns PmConfigs nil or error
+func (oo *OpenOLT) Update_pm_config(device *voltha.Device, pmConfigs *voltha.PmConfigs) error {
+	return ErrNotImplemented
+}
+
+//Receive_packet_out sends packet out to the device
+func (oo *OpenOLT) Receive_packet_out(deviceID string, egressPortNo int, packet *openflow_13.OfpPacketOut) error {
+	log.Debugw("Receive_packet_out", log.Fields{"deviceId": deviceID, "egress_port_no": egressPortNo, "pkt": packet})
+	ctx := context.Background()
+	if handler := oo.getDeviceHandler(deviceID); handler != nil {
+		return handler.PacketOut(ctx, egressPortNo, packet)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": deviceID}, nil).Log()
+}
+
+//Suppress_event unimplemented
+func (oo *OpenOLT) Suppress_event(filter *voltha.EventFilter) error {
+	return ErrNotImplemented
+}
+
+//Unsuppress_event  unimplemented
+func (oo *OpenOLT) Unsuppress_event(filter *voltha.EventFilter) error {
+	return ErrNotImplemented
+}
+
+//Download_image unimplemented
+func (oo *OpenOLT) Download_image(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, ErrNotImplemented
+}
+
+//Get_image_download_status unimplemented
+func (oo *OpenOLT) Get_image_download_status(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, ErrNotImplemented
+}
+
+//Cancel_image_download unimplemented
+func (oo *OpenOLT) Cancel_image_download(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, ErrNotImplemented
+}
+
+//Activate_image_update unimplemented
+func (oo *OpenOLT) Activate_image_update(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, ErrNotImplemented
+}
+
+//Revert_image_update unimplemented
+func (oo *OpenOLT) Revert_image_update(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, ErrNotImplemented
+}
+
+// Enable_port to Enable PON/NNI interface
+func (oo *OpenOLT) Enable_port(deviceID string, port *voltha.Port) error {
+	log.Infow("Enable_port", log.Fields{"deviceId": deviceID, "port": port})
+	return oo.enableDisablePort(deviceID, port, true)
+}
+
+// Disable_port to Disable pon/nni interface
+func (oo *OpenOLT) Disable_port(deviceID string, port *voltha.Port) error {
+	log.Infow("Disable_port", log.Fields{"deviceId": deviceID, "port": port})
+	return oo.enableDisablePort(deviceID, port, false)
+}
+
+// enableDisablePort to Disable pon or Enable PON interface
+func (oo *OpenOLT) enableDisablePort(deviceID string, port *voltha.Port, enablePort bool) error {
+	log.Infow("enableDisablePort", log.Fields{"deviceId": deviceID, "port": port})
+	if port == nil {
+		return NewErrInvalidValue(log.Fields{
+			"reason":    "port cannot be nil",
+			"device-id": deviceID,
+			"port":      nil}, nil).Log()
+	}
+	if handler := oo.getDeviceHandler(deviceID); handler != nil {
+		log.Debugw("Enable_Disable_Port", log.Fields{"deviceId": deviceID, "port": port})
+		if enablePort {
+			if err := handler.EnablePort(port); err != nil {
+				log.Errorw("error-occurred-during-enable-port", log.Fields{"deviceID": deviceID, "port": port, "error": err})
+				return err
+			}
+		} else {
+			if err := handler.DisablePort(port); err != nil {
+				log.Errorw("error-occurred-during-disable-port", log.Fields{"Device": deviceID, "port": port})
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+//Child_device_lost deletes the ONU and its references from PONResources
+func (oo *OpenOLT) Child_device_lost(deviceID string, pPortNo uint32, onuID uint32) error {
+	log.Infow("Child-device-lost", log.Fields{"parentId": deviceID})
+	ctx := context.Background()
+	if handler := oo.getDeviceHandler(deviceID); handler != nil {
+		return handler.ChildDeviceLost(ctx, pPortNo, onuID)
+	}
+	return NewErrNotFound("device-handler", log.Fields{"device-id": deviceID}, nil).Log()
+}
diff --git a/internal/pkg/core/openolt_eventmgr.go b/internal/pkg/core/openolt_eventmgr.go
new file mode 100644
index 0000000..4e21d11
--- /dev/null
+++ b/internal/pkg/core/openolt_eventmgr.go
@@ -0,0 +1,504 @@
+/*
+ * 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 core provides APIs for the openOLT adapter
+package core
+
+import (
+	ctx "context"
+	"fmt"
+	"strconv"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-protos/v3/go/common"
+	oop "github.com/opencord/voltha-protos/v3/go/openolt"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+const (
+	onuDiscoveryEvent           = "ONU_DISCOVERY"
+	onuLosEvent                 = "ONU_LOSS_OF_SIGNAL"
+	onuLobEvent                 = "ONU_LOSS_OF_BURST"
+	onuLopcMissEvent            = "ONU_LOPC_MISS"
+	onuLopcMicErrorEvent        = "ONU_LOPC_MIC_ERROR"
+	oltLosEvent                 = "OLT_LOSS_OF_SIGNAL"
+	oltIndicationDown           = "OLT_DOWN_INDICATION"
+	onuDyingGaspEvent           = "ONU_DYING_GASP"
+	onuSignalsFailEvent         = "ONU_SIGNALS_FAIL"
+	onuStartupFailEvent         = "ONU_STARTUP_FAIL"
+	onuSignalDegradeEvent       = "ONU_SIGNAL_DEGRADE"
+	onuDriftOfWindowEvent       = "ONU_DRIFT_OF_WINDOW"
+	onuActivationFailEvent      = "ONU_ACTIVATION_FAIL"
+	onuProcessingErrorEvent     = "ONU_PROCESSING_ERROR"
+	onuTiwiEvent                = "ONU_TRANSMISSION_WARNING"
+	onuLossOmciEvent            = "ONU_LOSS_OF_OMCI_CHANNEL"
+	onuLossOfKeySyncEvent       = "ONU_LOSS_OF_KEY_SYNC"
+	onuLossOfFrameEvent         = "ONU_LOSS_OF_FRAME"
+	onuLossOfPloamEvent         = "ONU_LOSS_OF_PLOAM"
+	ponIntfDownIndiction        = "OLT_PON_INTERFACE_DOWN"
+	onuDeactivationFailureEvent = "ONU_DEACTIVATION_FAILURE"
+)
+
+const (
+	pon           = voltha.EventSubCategory_PON
+	olt           = voltha.EventSubCategory_OLT
+	ont           = voltha.EventSubCategory_ONT
+	onu           = voltha.EventSubCategory_ONU
+	nni           = voltha.EventSubCategory_NNI
+	service       = voltha.EventCategory_SERVICE
+	security      = voltha.EventCategory_SECURITY
+	equipment     = voltha.EventCategory_EQUIPMENT
+	processing    = voltha.EventCategory_PROCESSING
+	environment   = voltha.EventCategory_ENVIRONMENT
+	communication = voltha.EventCategory_COMMUNICATION
+)
+
+const (
+	// statusCheckOn represents status check On
+	statusCheckOn = "on"
+	// statusCheckOff represents status check Off
+	statusCheckOff = "off"
+	// operationStateUp represents operation state Up
+	operationStateUp = "up"
+	// operationStateDown represents operation state Down
+	operationStateDown = "down"
+	// base10 represents base 10 conversion
+	base10 = 10
+)
+
+// OpenOltEventMgr struct contains
+type OpenOltEventMgr struct {
+	eventProxy adapterif.EventProxy
+	handler    *DeviceHandler
+}
+
+// NewEventMgr is a Function to get a new event manager struct for the OpenOLT to process and publish OpenOLT event
+func NewEventMgr(eventProxy adapterif.EventProxy, handler *DeviceHandler) *OpenOltEventMgr {
+	var em OpenOltEventMgr
+	em.eventProxy = eventProxy
+	em.handler = handler
+	return &em
+}
+
+// ProcessEvents is function to process and publish OpenOLT event
+func (em *OpenOltEventMgr) ProcessEvents(alarmInd *oop.AlarmIndication, deviceID string, raisedTs int64) error {
+	var err error
+	switch alarmInd.Data.(type) {
+	case *oop.AlarmIndication_LosInd:
+		log.Infow("Received LOS indication", log.Fields{"alarm_ind": alarmInd})
+		err = em.oltLosIndication(alarmInd.GetLosInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuAlarmInd:
+		log.Infow("Received onu alarm indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuAlarmIndication(alarmInd.GetOnuAlarmInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_DyingGaspInd:
+		log.Infow("Received dying gasp indication", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuDyingGaspIndication(alarmInd.GetDyingGaspInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuActivationFailInd:
+		log.Infow("Received onu activation fail indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuActivationFailIndication(alarmInd.GetOnuActivationFailInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuLossOmciInd:
+		log.Infow("Received onu loss omci indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuLossOmciIndication(alarmInd.GetOnuLossOmciInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuDriftOfWindowInd:
+		log.Infow("Received onu drift of window indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuDriftOfWindowIndication(alarmInd.GetOnuDriftOfWindowInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuSignalDegradeInd:
+		log.Infow("Received onu signal degrade indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuSignalDegradeIndication(alarmInd.GetOnuSignalDegradeInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuSignalsFailInd:
+		log.Infow("Received onu signal fail indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuSignalsFailIndication(alarmInd.GetOnuSignalsFailInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuStartupFailInd:
+		log.Infow("Received onu startup fail indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuStartupFailedIndication(alarmInd.GetOnuStartupFailInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuTiwiInd:
+		log.Infow("Received onu transmission warning indication ", log.Fields{"alarm_ind": alarmInd})
+		log.Infow("Not implemented yet", log.Fields{"alarm_ind": "Onu-Transmission-indication"})
+	case *oop.AlarmIndication_OnuLossOfSyncFailInd:
+		log.Infow("Received onu Loss of Sync Fail indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuLossOfSyncIndication(alarmInd.GetOnuLossOfSyncFailInd(), deviceID, raisedTs)
+	case *oop.AlarmIndication_OnuItuPonStatsInd:
+		log.Infow("Received onu Itu Pon Stats indication ", log.Fields{"alarm_ind": alarmInd})
+		log.Infow("Not implemented yet", log.Fields{"alarm_ind": alarmInd})
+	case *oop.AlarmIndication_OnuDeactivationFailureInd:
+		log.Infow("Received onu deactivation failure indication ", log.Fields{"alarm_ind": alarmInd})
+		err = em.onuDeactivationFailureIndication(alarmInd.GetOnuDeactivationFailureInd(), deviceID, raisedTs)
+	default:
+		err = NewErrInvalidValue(log.Fields{"indication-type": alarmInd}, nil)
+	}
+	if err != nil {
+		return NewErrCommunication("publish-message", log.Fields{"indication-type": alarmInd}, err).Log()
+	}
+	return nil
+}
+
+// oltUpDownIndication handles Up and Down state of an OLT
+func (em *OpenOltEventMgr) oltUpDownIndication(oltIndication *oop.OltIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["oper-state"] = oltIndication.OperState
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if oltIndication.OperState == operationStateDown {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", oltIndicationDown, "RAISE_EVENT")
+	} else if oltIndication.OperState == operationStateUp {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", oltIndicationDown, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, olt, raisedTs); err != nil {
+		log.Errorw("Failed to send OLT event", log.Fields{"err": err})
+		return err
+	}
+	log.Infow("OLT UpDown event sent to KAFKA", log.Fields{})
+	return nil
+}
+
+// OnuDiscoveryIndication is an exported method to handle ONU discovery event
+func (em *OpenOltEventMgr) OnuDiscoveryIndication(onuDisc *oop.OnuDiscIndication, deviceID string, OnuID uint32, serialNumber string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["onu-id"] = strconv.FormatUint(uint64(OnuID), base10)
+	context["intf-id"] = strconv.FormatUint(uint64(onuDisc.IntfId), base10)
+	context["serial-number"] = serialNumber
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	de.DeviceEventName = fmt.Sprintf("%s_%s", onuDiscoveryEvent, "RAISE_EVENT")
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU discovery event", log.Fields{"serial-number": serialNumber, "intf-id": onuDisc.IntfId})
+		return err
+	}
+	log.Infow("ONU discovery event sent to KAFKA", log.Fields{"serial-number": serialNumber, "intf-id": onuDisc.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) oltLosIndication(oltLos *oop.LosIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["intf-id"] = strconv.FormatUint(uint64(oltLos.IntfId), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if oltLos.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", oltLosEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", oltLosEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, olt, raisedTs); err != nil {
+		log.Errorw("Failed to send OLT loss of signal event", log.Fields{"intf-id": oltLos.IntfId})
+		return err
+	}
+	log.Infow("OLT LOS event sent to KAFKA", log.Fields{"intf-id": oltLos.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuDyingGaspIndication(dgi *oop.DyingGaspIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	var serialNumber string
+	context := make(map[string]string)
+	/* Populating event context */
+	serialNumber = ""
+	onu := em.handler.formOnuKey(dgi.IntfId, dgi.OnuId)
+	if onu, ok := em.handler.onus.Load(onu); ok {
+		serialNumber = onu.(*OnuDevice).serialNumber
+	}
+	context["serial-number"] = serialNumber
+	context["intf-id"] = strconv.FormatUint(uint64(dgi.IntfId), base10)
+	context["onu-id"] = strconv.FormatUint(uint64(dgi.OnuId), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	de.DeviceEventName = fmt.Sprintf("%s_%s", onuDyingGaspEvent, "EVENT")
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU Dying gasp event", log.Fields{"intf-id": dgi.IntfId, "onu-id": dgi.OnuId})
+		return err
+	}
+	log.Infow("ONU dying gasp event sent to KAFKA", log.Fields{"intf-id": dgi.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuAlarmIndication(onuAlarm *oop.OnuAlarmIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["intf-id"] = strconv.FormatUint(uint64(onuAlarm.IntfId), base10)
+	context["onu-id"] = strconv.FormatUint(uint64(onuAlarm.OnuId), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuAlarm.LosStatus == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLosEvent, "RAISE_EVENT")
+	} else if onuAlarm.LosStatus == statusCheckOff {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLosEvent, "CLEAR_EVENT")
+	} else if onuAlarm.LobStatus == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLobEvent, "RAISE_EVENT")
+	} else if onuAlarm.LobStatus == statusCheckOff {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLobEvent, "CLEAR_EVENT")
+	} else if onuAlarm.LopcMissStatus == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLopcMissEvent, "RAISE_EVENT")
+	} else if onuAlarm.LopcMissStatus == statusCheckOff {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLopcMissEvent, "CLEAR_EVENT")
+	} else if onuAlarm.LopcMicErrorStatus == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLopcMicErrorEvent, "RAISE_EVENT")
+	} else if onuAlarm.LopcMicErrorStatus == statusCheckOff {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLopcMicErrorEvent, "CLEAR_EVENT")
+	} else if onuAlarm.LofiStatus == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOfFrameEvent, "RAISE_EVENT")
+	} else if onuAlarm.LofiStatus == statusCheckOff {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOfFrameEvent, "CLEAR_EVENT")
+	} else if onuAlarm.LoamiStatus == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOfPloamEvent, "RAISE_EVENT")
+	} else if onuAlarm.LoamiStatus == statusCheckOff {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOfPloamEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, onu, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU Los event", log.Fields{"onu-id": onuAlarm.OnuId, "intf-id": onuAlarm.IntfId})
+		return err
+	}
+	log.Infow("ONU LOS event sent to KAFKA", log.Fields{"onu-id": onuAlarm.OnuId, "intf-id": onuAlarm.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuActivationFailIndication(oaf *oop.OnuActivationFailureIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["intf-id"] = strconv.FormatUint(uint64(oaf.IntfId), base10)
+	context["onu-id"] = strconv.FormatUint(uint64(oaf.OnuId), base10)
+	context["fail-reason"] = strconv.FormatUint(uint64(oaf.FailReason), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	de.DeviceEventName = fmt.Sprintf("%s_%s", onuActivationFailEvent, "RAISE_EVENT")
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU activation failure event", log.Fields{"onu-id": oaf.OnuId, "intf-id": oaf.IntfId})
+		return err
+	}
+	log.Infow("ONU activation failure event sent to KAFKA", log.Fields{"onu-id": oaf.OnuId, "intf-id": oaf.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuLossOmciIndication(onuLossOmci *oop.OnuLossOfOmciChannelIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["intf-id"] = strconv.FormatUint(uint64(onuLossOmci.IntfId), base10)
+	context["onu-id"] = strconv.FormatUint(uint64(onuLossOmci.OnuId), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuLossOmci.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOmciEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOmciEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU loss of OMCI channel event", log.Fields{"onu-id": onuLossOmci.OnuId, "intf-id": onuLossOmci.IntfId})
+		return err
+	}
+	log.Infow("ONU loss of OMCI channel event sent to KAFKA", log.Fields{"onu-id": onuLossOmci.OnuId, "intf-id": onuLossOmci.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuDriftOfWindowIndication(onuDriftWindow *oop.OnuDriftOfWindowIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["intf-id"] = strconv.FormatUint(uint64(onuDriftWindow.IntfId), base10)
+	context["onu-id"] = strconv.FormatUint(uint64(onuDriftWindow.OnuId), base10)
+	context["drift"] = strconv.FormatUint(uint64(onuDriftWindow.Drift), base10)
+	context["new-eqd"] = strconv.FormatUint(uint64(onuDriftWindow.NewEqd), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuDriftWindow.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuDriftOfWindowEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuDriftOfWindowEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU drift of window event", log.Fields{"onu-id": onuDriftWindow.OnuId, "intf-id": onuDriftWindow.IntfId})
+		return err
+	}
+	log.Infow("ONU drift of window event sent to KAFKA", log.Fields{"onu-id": onuDriftWindow.OnuId, "intf-id": onuDriftWindow.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuSignalDegradeIndication(onuSignalDegrade *oop.OnuSignalDegradeIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["intf-id"] = strconv.FormatUint(uint64(onuSignalDegrade.IntfId), base10)
+	context["onu-id"] = strconv.FormatUint(uint64(onuSignalDegrade.OnuId), base10)
+	context["inverse-bit-error-rate"] = strconv.FormatUint(uint64(onuSignalDegrade.InverseBitErrorRate), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuSignalDegrade.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuSignalDegradeEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuSignalDegradeEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU signals degrade event", log.Fields{"onu-id": onuSignalDegrade.OnuId, "intf-id": onuSignalDegrade.IntfId})
+		return err
+	}
+	log.Infow("ONU signal degrade event sent to KAFKA", log.Fields{"onu-id": onuSignalDegrade.OnuId, "intf-id": onuSignalDegrade.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuSignalsFailIndication(onuSignalsFail *oop.OnuSignalsFailureIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["onu-id"] = strconv.FormatUint(uint64(onuSignalsFail.OnuId), base10)
+	context["intf-id"] = strconv.FormatUint(uint64(onuSignalsFail.IntfId), base10)
+	context["inverse-bit-error-rate"] = strconv.FormatUint(uint64(onuSignalsFail.InverseBitErrorRate), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuSignalsFail.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuSignalsFailEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuSignalsFailEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU signals fail event", log.Fields{"onu-id": onuSignalsFail.OnuId, "intf-id": onuSignalsFail.IntfId})
+		return err
+	}
+	log.Infow("ONU signals fail event sent to KAFKA", log.Fields{"onu-id": onuSignalsFail.OnuId, "intf-id": onuSignalsFail.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuStartupFailedIndication(onuStartupFail *oop.OnuStartupFailureIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["onu-id"] = strconv.FormatUint(uint64(onuStartupFail.OnuId), base10)
+	context["intf-id"] = strconv.FormatUint(uint64(onuStartupFail.IntfId), base10)
+
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuStartupFail.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuStartupFailEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuStartupFailEvent, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, pon, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU startup fail event", log.Fields{"onu-id": onuStartupFail.OnuId, "intf-id": onuStartupFail.IntfId})
+		return err
+	}
+	log.Infow("ONU startup fail event sent to KAFKA", log.Fields{"onu-id": onuStartupFail.OnuId, "intf-id": onuStartupFail.IntfId})
+	return nil
+}
+
+func (em *OpenOltEventMgr) onuLossOfSyncIndication(onuLOKI *oop.OnuLossOfKeySyncFailureIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["onu-id"] = strconv.FormatUint(uint64(onuLOKI.OnuId), base10)
+	context["intf-id"] = strconv.FormatUint(uint64(onuLOKI.IntfId), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	if onuLOKI.Status == statusCheckOn {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOfKeySyncEvent, "RAISE_EVENT")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", onuLossOfKeySyncEvent, "CLEAR_EVENT")
+	}
+
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, security, onu, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU loss of key sync event", log.Fields{"onu-id": onuLOKI.OnuId, "intf-id": onuLOKI.IntfId})
+		return err
+	}
+	log.Infow("ONU loss of key sync event sent to KAFKA", log.Fields{"onu-id": onuLOKI.OnuId, "intf-id": onuLOKI.IntfId})
+	return nil
+}
+
+// oltIntfOperIndication handles Up and Down state of an OLT PON ports
+func (em *OpenOltEventMgr) oltIntfOperIndication(ifindication *oop.IntfOperIndication, deviceID string, raisedTs int64) {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	portID := IntfIDToPortNo(ifindication.IntfId, voltha.Port_PON_OLT)
+	device, err := em.handler.coreProxy.GetDevice(ctx.Background(), deviceID, deviceID)
+	if err != nil {
+		log.Errorw("Error while fetching Device object", log.Fields{"DeviceId": deviceID})
+	}
+	for _, port := range device.Ports {
+		if port.PortNo == portID {
+			// Events are suppressed if the Port Adminstate is not enabled.
+			if port.AdminState != common.AdminState_ENABLED {
+				log.Infow("Port disable/enable event not generated because, The port is not enabled by operator", log.Fields{"deviceId": deviceID, "port": port})
+				return
+			}
+			break
+		}
+	}
+	/* Populating event context */
+	context["oper-state"] = ifindication.GetOperState()
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+
+	if ifindication.GetOperState() == operationStateDown {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", ponIntfDownIndiction, "RAISE_EVENT")
+	} else if ifindication.OperState == operationStateUp {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", ponIntfDownIndiction, "CLEAR_EVENT")
+	}
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, communication, olt, raisedTs); err != nil {
+		log.Errorw("failed-to-send-olt-intf-oper-status-event", log.Fields{"err": err})
+	}
+	log.Info("sent-olt-intf-oper-status-event-to-kafka")
+}
+
+func (em *OpenOltEventMgr) onuDeactivationFailureIndication(onuDFI *oop.OnuDeactivationFailureIndication, deviceID string, raisedTs int64) error {
+	var de voltha.DeviceEvent
+	context := make(map[string]string)
+	/* Populating event context */
+	context["onu-id"] = strconv.FormatUint(uint64(onuDFI.OnuId), base10)
+	context["intf-id"] = strconv.FormatUint(uint64(onuDFI.IntfId), base10)
+	context["failure-reason"] = strconv.FormatUint(uint64(onuDFI.FailReason), base10)
+	/* Populating device event body */
+	de.Context = context
+	de.ResourceId = deviceID
+	de.DeviceEventName = onuDeactivationFailureEvent
+
+	/* Send event to KAFKA */
+	if err := em.eventProxy.SendDeviceEvent(&de, equipment, onu, raisedTs); err != nil {
+		log.Errorw("Failed to send ONU deactivation failure event", log.Fields{"onu-id": onuDFI.OnuId, "intf-id": onuDFI.IntfId})
+		return err
+	}
+	log.Infow("ONU deactivation failure event sent to KAFKA", log.Fields{"onu-id": onuDFI.OnuId, "intf-id": onuDFI.IntfId})
+	return nil
+}
diff --git a/internal/pkg/core/openolt_eventmgr_test.go b/internal/pkg/core/openolt_eventmgr_test.go
new file mode 100644
index 0000000..d5f1520
--- /dev/null
+++ b/internal/pkg/core/openolt_eventmgr_test.go
@@ -0,0 +1,149 @@
+/*
+ * 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 core provides APIs for the openOLT adapter
+package core
+
+import (
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/opencord/voltha-openolt-adapter/pkg/mocks"
+	oop "github.com/opencord/voltha-protos/v3/go/openolt"
+)
+
+func mockEventMgr() *OpenOltEventMgr {
+	ep := &mocks.MockEventProxy{}
+	dh := &DeviceHandler{}
+	dh.onus = sync.Map{}
+	dh.onus.Store(dh.formOnuKey(1, 1), &OnuDevice{deviceID: "TEST_ONU",
+		deviceType:   "ONU",
+		serialNumber: "TEST_ONU_123",
+		onuID:        1, intfID: 1})
+	return NewEventMgr(ep, dh)
+}
+func TestOpenOltEventMgr_ProcessEvents(t *testing.T) {
+	em := mockEventMgr()
+	type args struct {
+		alarmInd *oop.AlarmIndication
+		deviceID string
+		raisedTs int64
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		// LosIndication alarms
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_LosInd{LosInd: &oop.LosIndication{IntfId: 1, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_LosInd{LosInd: &oop.LosIndication{IntfId: 1}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_LosInd{LosInd: &oop.LosIndication{IntfId: 1, Status: "on"}}}}},
+
+		// OnuAlarmIndication alams
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LosStatus: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LosStatus: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LobStatus: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LobStatus: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LopcMissStatus: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LopcMissStatus: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LopcMicErrorStatus: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LopcMicErrorStatus: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LofiStatus: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LofiStatus: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LoamiStatus: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LoamiStatus: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &oop.OnuAlarmIndication{IntfId: 1, OnuId: 3, LosStatus: "on"}}}}},
+
+		// AlarmIndication_DyingGaspInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_DyingGaspInd{DyingGaspInd: &oop.DyingGaspIndication{IntfId: 1, OnuId: 1, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_DyingGaspInd{DyingGaspInd: &oop.DyingGaspIndication{IntfId: 1, OnuId: 1, Status: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_DyingGaspInd{DyingGaspInd: &oop.DyingGaspIndication{IntfId: 1, OnuId: 1}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_DyingGaspInd{DyingGaspInd: &oop.DyingGaspIndication{IntfId: 1, OnuId: 1}}}}},
+
+		// AlarmIndication_OnuActivationFailInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuActivationFailInd{OnuActivationFailInd: &oop.OnuActivationFailureIndication{IntfId: 1, OnuId: 3}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuActivationFailInd{OnuActivationFailInd: &oop.OnuActivationFailureIndication{IntfId: 1, OnuId: 3}}}}},
+
+		// AlarmIndication_OnuLossOmciInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuLossOmciInd{OnuLossOmciInd: &oop.OnuLossOfOmciChannelIndication{IntfId: 1, OnuId: 3, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuLossOmciInd{OnuLossOmciInd: &oop.OnuLossOfOmciChannelIndication{IntfId: 1, OnuId: 3, Status: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuLossOmciInd{OnuLossOmciInd: &oop.OnuLossOfOmciChannelIndication{IntfId: 1, OnuId: 3, Status: "on"}}}}},
+
+		// AlarmIndication_OnuDriftOfWindowInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuDriftOfWindowInd{OnuDriftOfWindowInd: &oop.OnuDriftOfWindowIndication{IntfId: 1, OnuId: 3, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuDriftOfWindowInd{OnuDriftOfWindowInd: &oop.OnuDriftOfWindowIndication{IntfId: 1, OnuId: 3, Status: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuDriftOfWindowInd{OnuDriftOfWindowInd: &oop.OnuDriftOfWindowIndication{IntfId: 1, OnuId: 3, Drift: 10, NewEqd: 10}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuDriftOfWindowInd{OnuDriftOfWindowInd: &oop.OnuDriftOfWindowIndication{IntfId: 1, OnuId: 3, Status: "on"}}}}},
+
+		// AlarmIndication_OnuSignalDegradeInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalDegradeInd{OnuSignalDegradeInd: &oop.OnuSignalDegradeIndication{IntfId: 1, OnuId: 3, Status: "on", InverseBitErrorRate: 100}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalDegradeInd{OnuSignalDegradeInd: &oop.OnuSignalDegradeIndication{IntfId: 1, OnuId: 3, Status: "off", InverseBitErrorRate: 100}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalDegradeInd{OnuSignalDegradeInd: &oop.OnuSignalDegradeIndication{IntfId: 1, OnuId: 3, InverseBitErrorRate: 100}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalDegradeInd{OnuSignalDegradeInd: &oop.OnuSignalDegradeIndication{IntfId: 1, OnuId: 3, InverseBitErrorRate: 100}}}}},
+
+		// AlarmIndication_OnuSignalsFailInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalsFailInd{OnuSignalsFailInd: &oop.OnuSignalsFailureIndication{IntfId: 1, OnuId: 3, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalsFailInd{OnuSignalsFailInd: &oop.OnuSignalsFailureIndication{IntfId: 1, OnuId: 3, Status: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalsFailInd{OnuSignalsFailInd: &oop.OnuSignalsFailureIndication{IntfId: 1, OnuId: 3, InverseBitErrorRate: 100}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuSignalsFailInd{OnuSignalsFailInd: &oop.OnuSignalsFailureIndication{IntfId: 1, OnuId: 3, InverseBitErrorRate: 100}}}}},
+
+		// AlarmIndication_OnuProcessingErrorInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuProcessingErrorInd{OnuProcessingErrorInd: &oop.OnuProcessingErrorIndication{IntfId: 1, OnuId: 3}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuProcessingErrorInd{OnuProcessingErrorInd: &oop.OnuProcessingErrorIndication{IntfId: 1, OnuId: 3}}}}},
+
+		// AlarmIndication_OnuTiwiInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuTiwiInd{OnuTiwiInd: &oop.OnuTransmissionInterferenceWarning{IntfId: 1, OnuId: 3, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuTiwiInd{OnuTiwiInd: &oop.OnuTransmissionInterferenceWarning{IntfId: 1, OnuId: 3, Status: "on", Drift: 100}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuTiwiInd{OnuTiwiInd: &oop.OnuTransmissionInterferenceWarning{IntfId: 1, OnuId: 3}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuTiwiInd{OnuTiwiInd: &oop.OnuTransmissionInterferenceWarning{IntfId: 1, OnuId: 3}}}}},
+
+		// AlarmIndication_onuLossOfKeySyncInd
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuLossOfSyncFailInd{OnuLossOfSyncFailInd: &oop.OnuLossOfKeySyncFailureIndication{IntfId: 1, OnuId: 3, Status: "on"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+		{"ProcessEvents-", args{alarmInd: &oop.AlarmIndication{Data: &oop.AlarmIndication_OnuLossOfSyncFailInd{OnuLossOfSyncFailInd: &oop.OnuLossOfKeySyncFailureIndication{IntfId: 1, OnuId: 3, Status: "off"}}}, deviceID: "olt", raisedTs: time.Now().Unix()}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			em.ProcessEvents(tt.args.alarmInd, tt.args.deviceID, tt.args.raisedTs)
+		})
+	}
+}
+
+func TestOpenOltEventMgr_OnuDiscoveryIndication(t *testing.T) {
+	em := mockEventMgr()
+	type args struct {
+		onuDisc      *oop.OnuDiscIndication
+		deviceID     string
+		OnuID        uint32
+		serialNumber string
+		raisedTs     int64
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		{"OnuDiscoveryIndication", args{onuDisc: &oop.OnuDiscIndication{IntfId: 1, SerialNumber: &oop.SerialNumber{VendorId: []byte("TWSH"), VendorSpecific: []byte("1234")}}, deviceID: "olt", OnuID: 3, serialNumber: "1234", raisedTs: time.Now().Unix()}},
+		{"OnuDiscoveryIndication", args{onuDisc: &oop.OnuDiscIndication{}, raisedTs: time.Now().Unix()}},
+		{"OnuDiscoveryIndication", args{onuDisc: &oop.OnuDiscIndication{}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			em.OnuDiscoveryIndication(tt.args.onuDisc, tt.args.deviceID, tt.args.OnuID, tt.args.serialNumber, tt.args.raisedTs)
+		})
+	}
+}
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
new file mode 100644
index 0000000..fe03a79
--- /dev/null
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -0,0 +1,3044 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"crypto/md5"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"math/big"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
+	rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
+	"github.com/opencord/voltha-protos/v3/go/common"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	openoltpb2 "github.com/opencord/voltha-protos/v3/go/openolt"
+	tp_pb "github.com/opencord/voltha-protos/v3/go/tech_profile"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+
+	//deepcopy "github.com/getlantern/deepcopy"
+	"github.com/EagleChen/mapmutex"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+const (
+	// Flow categories
+
+	//HsiaFlow flow category
+	HsiaFlow = "HSIA_FLOW"
+
+	//EapolFlow flow category
+	EapolFlow = "EAPOL_FLOW"
+
+	//DhcpFlow flow category
+	DhcpFlow = "DHCP_FLOW"
+
+	//MulticastFlow flow category
+	MulticastFlow = "MULTICAST_FLOW"
+
+	//IgmpFlow flow category
+	IgmpFlow = "IGMP_FLOW"
+
+	//IPProtoDhcp flow category
+	IPProtoDhcp = 17
+
+	//IPProtoIgmp flow category
+	IPProtoIgmp = 2
+
+	//EapEthType eapethtype value
+	EapEthType = 0x888e
+	//LldpEthType lldp ethtype value
+	LldpEthType = 0x88cc
+	//IPv4EthType IPv4 ethernet type value
+	IPv4EthType = 0x800
+
+	//IgmpProto proto value
+	IgmpProto = 2
+
+	//FIXME - see also BRDCM_DEFAULT_VLAN in broadcom_onu.py
+
+	//ReservedVlan Transparent Vlan
+	ReservedVlan = 4095
+
+	//DefaultMgmtVlan default vlan value
+	DefaultMgmtVlan = 4091
+
+	// Openolt Flow
+
+	//Upstream constant
+	Upstream = "upstream"
+	//Downstream constant
+	Downstream = "downstream"
+	//Multicast constant
+	Multicast = "multicast"
+	//PacketTagType constant
+	PacketTagType = "pkt_tag_type"
+	//Untagged constant
+	Untagged = "untagged"
+	//SingleTag constant
+	SingleTag = "single_tag"
+	//DoubleTag constant
+	DoubleTag = "double_tag"
+
+	// classifierInfo
+
+	//EthType constant
+	EthType = "eth_type"
+	//EthDst constant
+	EthDst = "eth_dst"
+	//TPID constant
+	TPID = "tpid"
+	//IPProto constant
+	IPProto = "ip_proto"
+	//InPort constant
+	InPort = "in_port"
+	//VlanVid constant
+	VlanVid = "vlan_vid"
+	//VlanPcp constant
+	VlanPcp = "vlan_pcp"
+
+	//UDPDst constant
+	UDPDst = "udp_dst"
+	//UDPSrc constant
+	UDPSrc = "udp_src"
+	//Ipv4Dst constant
+	Ipv4Dst = "ipv4_dst"
+	//Ipv4Src constant
+	Ipv4Src = "ipv4_src"
+	//Metadata constant
+	Metadata = "metadata"
+	//TunnelID constant
+	TunnelID = "tunnel_id"
+	//Output constant
+	Output = "output"
+	//GroupID constant
+	GroupID = "group_id"
+	// Actions
+
+	//PopVlan constant
+	PopVlan = "pop_vlan"
+	//PushVlan constant
+	PushVlan = "push_vlan"
+	//TrapToHost constant
+	TrapToHost = "trap_to_host"
+	//MaxMeterBand constant
+	MaxMeterBand = 2
+	//VlanPCPMask contant
+	VlanPCPMask = 0xFF
+	//VlanvIDMask constant
+	VlanvIDMask = 0xFFF
+	//IntfID constant
+	IntfID = "intfId"
+	//OnuID constant
+	OnuID = "onuId"
+	//UniID constant
+	UniID = "uniId"
+	//PortNo constant
+	PortNo = "portNo"
+	//AllocID constant
+	AllocID = "allocId"
+
+	//NoneOnuID constant
+	NoneOnuID = -1
+	//NoneUniID constant
+	NoneUniID = -1
+	//NoneGemPortID constant
+	NoneGemPortID = -1
+
+	// BinaryStringPrefix is binary string prefix
+	BinaryStringPrefix = "0b"
+	// BinaryBit1 is binary bit 1 expressed as a character
+	BinaryBit1 = '1'
+)
+
+type gemPortKey struct {
+	intfID  uint32
+	gemPort uint32
+}
+
+type pendingFlowDeleteKey struct {
+	intfID uint32
+	onuID  uint32
+	uniID  uint32
+}
+
+type tpLockKey struct {
+	intfID uint32
+	onuID  uint32
+	uniID  uint32
+}
+
+type schedQueue struct {
+	direction    tp_pb.Direction
+	intfID       uint32
+	onuID        uint32
+	uniID        uint32
+	tpID         uint32
+	uniPort      uint32
+	tpInst       *tp.TechProfile
+	meterID      uint32
+	flowMetadata *voltha.FlowMetadata
+}
+
+type queueInfoBrief struct {
+	gemPortID       uint32
+	servicePriority uint32
+}
+
+//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
+type OpenOltFlowMgr struct {
+	techprofile        map[uint32]tp.TechProfileIf
+	deviceHandler      *DeviceHandler
+	resourceMgr        *rsrcMgr.OpenOltResourceMgr
+	onuIdsLock         sync.RWMutex
+	flowsUsedByGemPort map[gemPortKey][]uint32            //gem port id to flow ids
+	packetInGemPort    map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
+	onuGemInfo         map[uint32][]rsrcMgr.OnuGemInfo    //onu, gem and uni info local cache
+	lockCache          sync.RWMutex
+	pendingFlowDelete  sync.Map
+	// The mapmutex.Mutex can be fine tuned to use mapmutex.NewCustomizedMapMutex
+	perUserFlowHandleLock    *mapmutex.Mutex
+	interfaceToMcastQueueMap map[uint32]*queueInfoBrief /*pon interface -> multicast queue map. Required to assign GEM to a bucket during group population*/
+}
+
+//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
+func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr) *OpenOltFlowMgr {
+	log.Info("Initializing flow manager")
+	var flowMgr OpenOltFlowMgr
+	var err error
+	var idx uint32
+
+	flowMgr.deviceHandler = dh
+	flowMgr.resourceMgr = rMgr
+	flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
+	if err = flowMgr.populateTechProfilePerPonPort(); err != nil {
+		log.Error("Error while populating tech profile mgr\n")
+		return nil
+	}
+	flowMgr.onuIdsLock = sync.RWMutex{}
+	flowMgr.flowsUsedByGemPort = make(map[gemPortKey][]uint32)
+	flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
+	flowMgr.onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo)
+	ponPorts := rMgr.DevInfo.GetPonPorts()
+	//Load the onugem info cache from kv store on flowmanager start
+	for idx = 0; idx < ponPorts; idx++ {
+		if flowMgr.onuGemInfo[idx], err = rMgr.GetOnuGemInfo(ctx, idx); err != nil {
+			log.Error("Failed to load onu gem info cache")
+		}
+		//Load flowID list per gem map per interface from the kvstore.
+		flowMgr.loadFlowIDlistForGem(ctx, idx)
+	}
+	flowMgr.lockCache = sync.RWMutex{}
+	flowMgr.pendingFlowDelete = sync.Map{}
+	flowMgr.perUserFlowHandleLock = mapmutex.NewMapMutex()
+	flowMgr.interfaceToMcastQueueMap = make(map[uint32]*queueInfoBrief)
+	//load interface to multicast queue map from kv store
+	flowMgr.loadInterfaceToMulticastQueueMap(ctx)
+	log.Info("Initialization of  flow manager success!!")
+	return &flowMgr
+}
+
+func (f *OpenOltFlowMgr) generateStoredFlowID(flowID uint32, direction string) (uint64, error) {
+	if direction == Upstream {
+		log.Debug("upstream flow, shifting id")
+		return 0x1<<15 | uint64(flowID), nil
+	} else if direction == Downstream {
+		log.Debug("downstream flow, not shifting id")
+		return uint64(flowID), nil
+	} else if direction == Multicast {
+		log.Debug("multicast flow, shifting id")
+		return 0x2<<15 | uint64(flowID), nil
+	} else {
+		return 0, NewErrInvalidValue(log.Fields{"direction": direction}, nil).Log()
+	}
+}
+
+func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) {
+	log.Debug("Registering Flow for Device ", log.Fields{"flow": flowFromCore},
+		log.Fields{"device": f.deviceHandler.deviceID})
+	gemPK := gemPortKey{uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId)}
+	flowIDList, ok := f.flowsUsedByGemPort[gemPK]
+	if !ok {
+		flowIDList = []uint32{deviceFlow.FlowId}
+	}
+	flowIDList = appendUnique(flowIDList, deviceFlow.FlowId)
+	f.flowsUsedByGemPort[gemPK] = flowIDList
+	// update the flowids for a gem to the KVstore
+	f.resourceMgr.UpdateFlowIDsForGem(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowIDList)
+}
+
+func (f *OpenOltFlowMgr) divideAndAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
+	classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
+	UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) {
+	var allocID uint32
+	var gemPorts []uint32
+	var TpInst *tp.TechProfile
+
+	log.Infow("Dividing flow", log.Fields{"intfId": intfID, "onuId": onuID, "uniId": uniID, "portNo": portNo,
+		"classifier": classifierInfo, "action": actionInfo, "UsMeterID": UsMeterID, "DsMeterID": DsMeterID, "TpID": TpID})
+	// only create tcont/gemports if there is actually an onu id.  otherwise BAL throws an error.  Usually this
+	// is because the flow is an NNI flow and there would be no onu resources associated with it
+	// TODO: properly deal with NNI flows
+	if onuID <= 0 {
+		log.Errorw("No onu id for flow", log.Fields{"portNo": portNo, "classifer": classifierInfo, "action": actionInfo})
+		return
+	}
+
+	uni := getUniPortPath(intfID, int32(onuID), int32(uniID))
+	log.Debugw("Uni port name", log.Fields{"uni": uni})
+
+	tpLockMapKey := tpLockKey{intfID, onuID, uniID}
+	if f.perUserFlowHandleLock.TryLock(tpLockMapKey) {
+		allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
+		if allocID == 0 || gemPorts == nil || TpInst == nil {
+			log.Error("alloc-id-gem-ports-tp-unavailable")
+			f.perUserFlowHandleLock.Unlock(tpLockMapKey)
+			return
+		}
+		args := make(map[string]uint32)
+		args[IntfID] = intfID
+		args[OnuID] = onuID
+		args[UniID] = uniID
+		args[PortNo] = portNo
+		args[AllocID] = allocID
+
+		/* Flows can be added specific to gemport if p-bits are received.
+		 * If no pbit mentioned then adding flows for all gemports
+		 */
+		f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
+		f.perUserFlowHandleLock.Unlock(tpLockMapKey)
+	} else {
+		log.Errorw("failed to acquire per user flow handle lock",
+			log.Fields{"intfId": intfID, "onuId": onuID, "uniId": uniID})
+		return
+	}
+}
+
+// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
+func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
+
+	log.Debugw("CreateSchedulerQueues", log.Fields{"Dir": sq.direction, "IntfID": sq.intfID,
+		"OnuID": sq.onuID, "UniID": sq.uniID, "TpID": sq.tpID, "MeterID": sq.meterID,
+		"TpInst": sq.tpInst, "flowMetadata": sq.flowMetadata})
+
+	Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
+	if err != nil {
+		return err
+	}
+
+	/* Lets make a simple assumption that if the meter-id is present on the KV store,
+	 * then the scheduler and queues configuration is applied on the OLT device
+	 * in the given direction.
+	 */
+
+	var SchedCfg *tp_pb.SchedulerConfig
+	KvStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
+	if err != nil {
+		log.Error("Failed to get meter for intf %d, onuid %d, uniid %d", sq.intfID, sq.onuID, sq.uniID)
+		return err
+	}
+	if KvStoreMeter != nil {
+		if KvStoreMeter.MeterId == sq.meterID {
+			log.Debug("Scheduler already created for upstream")
+			return nil
+		}
+		return NewErrInvalidValue(log.Fields{
+			"unsupported":       "meter-id",
+			"kv-store-meter-id": KvStoreMeter.MeterId,
+			"meter-id-in-flow":  sq.meterID}, nil).Log()
+	}
+
+	log.Debugw("Meter-does-not-exist-Creating-new", log.Fields{"MeterID": sq.meterID, "Direction": Direction})
+
+	if sq.direction == tp_pb.Direction_UPSTREAM {
+		SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst)
+	} else if sq.direction == tp_pb.Direction_DOWNSTREAM {
+		SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst)
+	}
+
+	if err != nil {
+		log.Errorw("Unable to get Scheduler config", log.Fields{"IntfID": sq.intfID, "Direction": sq.direction, "Error": err})
+		return err
+	}
+
+	var meterConfig *ofp.OfpMeterConfig
+	if sq.flowMetadata != nil {
+		for _, meter := range sq.flowMetadata.Meters {
+			if sq.meterID == meter.MeterId {
+				meterConfig = meter
+				log.Debugw("Found-meter-config-from-flowmetadata", log.Fields{"meterConfig": meterConfig})
+				break
+			}
+		}
+	} else {
+		log.Error("Flow-metadata-is-not-present-in-flow")
+	}
+	if meterConfig == nil {
+		return NewErrNotFound("meterbands", log.Fields{
+			"reason":        "Could-not-get-meterbands-from-flowMetadata",
+			"flow-metadata": sq.flowMetadata,
+			"meter-id":      sq.meterID}, nil).Log()
+	} else if len(meterConfig.Bands) < MaxMeterBand {
+		log.Errorw("Invalid-number-of-bands-in-meter", log.Fields{"Bands": meterConfig.Bands, "MeterID": sq.meterID})
+		return NewErrInvalidValue(log.Fields{
+			"reason":          "Invalid-number-of-bands-in-meter",
+			"meterband-count": len(meterConfig.Bands),
+			"metabands":       meterConfig.Bands,
+			"meter-id":        sq.meterID}, nil).Log()
+	}
+	cir := meterConfig.Bands[0].Rate
+	cbs := meterConfig.Bands[0].BurstSize
+	eir := meterConfig.Bands[1].Rate
+	ebs := meterConfig.Bands[1].BurstSize
+	pir := cir + eir
+	pbs := cbs + ebs
+	TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
+
+	TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst, SchedCfg, TrafficShaping)}
+
+	if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficShaping, TrafficSched); err != nil {
+		log.Errorw("Failed to push traffic scheduler and queues to device", log.Fields{"intfID": sq.intfID, "direction": sq.direction})
+		return err
+	}
+
+	/* After we successfully applied the scheduler configuration on the OLT device,
+	 * store the meter id on the KV store, for further reference.
+	 */
+	if err := f.resourceMgr.UpdateMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, meterConfig); err != nil {
+		log.Error("Failed to update meter id for onu %d, meterid %d", sq.onuID, sq.meterID)
+		return err
+	}
+	log.Debugw("updated-meter-info into KV store successfully", log.Fields{"Direction": Direction,
+		"Meter": meterConfig})
+	return nil
+}
+
+func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficShaping *tp_pb.TrafficShapingInfo, TrafficSched []*tp_pb.TrafficScheduler) error {
+
+	trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst, sq.direction)
+
+	if err != nil {
+		log.Errorw("Unable to construct traffic queue configuration", log.Fields{"intfID": sq.intfID, "direction": sq.direction})
+		return err
+	}
+
+	log.Debugw("Sending Traffic scheduler create to device", log.Fields{"Direction": sq.direction, "TrafficScheds": TrafficSched})
+	if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
+		IntfId: sq.intfID, OnuId: sq.onuID,
+		UniId: sq.uniID, PortNo: sq.uniPort,
+		TrafficScheds: TrafficSched}); err != nil {
+		log.Errorw("Failed to create traffic schedulers", log.Fields{"error": err})
+		return err
+	}
+
+	// On receiving the CreateTrafficQueues request, the driver should create corresponding
+	// downstream queues.
+	log.Debugw("Sending Traffic Queues create to device", log.Fields{"Direction": sq.direction, "TrafficQueues": trafficQueues})
+	if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
+		&tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
+			UniId: sq.uniID, PortNo: sq.uniPort,
+			TrafficQueues: trafficQueues}); err != nil {
+		log.Errorw("Failed to create traffic queues in device", log.Fields{"error": err})
+		return err
+	}
+
+	if sq.direction == tp_pb.Direction_DOWNSTREAM {
+		multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(sq.tpInst)
+		if len(multicastTrafficQueues) > 0 {
+			if _, present := f.interfaceToMcastQueueMap[sq.intfID]; !present {
+				//assumed that there is only one queue per PON for the multicast service
+				//the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
+				//just put it in interfaceToMcastQueueMap to use for building group members
+				multicastQueuePerPonPort := multicastTrafficQueues[0]
+				f.interfaceToMcastQueueMap[sq.intfID] = &queueInfoBrief{
+					gemPortID:       multicastQueuePerPonPort.GemportId,
+					servicePriority: multicastQueuePerPonPort.Priority,
+				}
+				//also store the queue info in kv store
+				f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID,
+					multicastQueuePerPonPort.GemportId,
+					multicastQueuePerPonPort.Priority)
+			}
+		}
+	}
+	return nil
+}
+
+// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
+func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
+
+	var Direction string
+	var SchedCfg *tp_pb.SchedulerConfig
+	var err error
+	log.Debugw("Removing schedulers and Queues in OLT", log.Fields{"Direction": sq.direction, "IntfID": sq.intfID,
+		"OnuID": sq.onuID, "UniID": sq.uniID, "UniPort": sq.uniPort})
+	if sq.direction == tp_pb.Direction_UPSTREAM {
+		SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst)
+		Direction = "upstream"
+	} else if sq.direction == tp_pb.Direction_DOWNSTREAM {
+		SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst)
+		Direction = "downstream"
+	}
+
+	if err != nil {
+		log.Errorw("Unable to get Scheduler config", log.Fields{"IntID": sq.intfID, "Direction": sq.direction, "Error": err})
+		return err
+	}
+
+	KVStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
+	if err != nil {
+		log.Errorf("Failed to get Meter for Onu %d", sq.onuID)
+		return err
+	}
+	if KVStoreMeter == nil {
+		log.Debugw("No-meter-has-been-installed-yet", log.Fields{"direction": Direction, "IntfID": sq.intfID, "OnuID": sq.onuID, "UniID": sq.uniID})
+		return nil
+	}
+	cir := KVStoreMeter.Bands[0].Rate
+	cbs := KVStoreMeter.Bands[0].BurstSize
+	eir := KVStoreMeter.Bands[1].Rate
+	ebs := KVStoreMeter.Bands[1].BurstSize
+	pir := cir + eir
+	pbs := cbs + ebs
+
+	TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
+
+	TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst, SchedCfg, TrafficShaping)}
+
+	TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst, sq.direction)
+	if err != nil {
+		log.Errorw("Unable to construct traffic queue configuration", log.Fields{"intfID": sq.intfID, "direction": sq.direction})
+		return err
+	}
+
+	if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
+		&tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
+			UniId: sq.uniID, PortNo: sq.uniPort,
+			TrafficQueues: TrafficQueues}); err != nil {
+		log.Errorw("Failed to remove traffic queues", log.Fields{"error": err})
+		return err
+	}
+	log.Debug("Removed traffic queues successfully")
+	if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
+		IntfId: sq.intfID, OnuId: sq.onuID,
+		UniId: sq.uniID, PortNo: sq.uniPort,
+		TrafficScheds: TrafficSched}); err != nil {
+		log.Errorw("failed to remove traffic schedulers", log.Fields{"error": err})
+		return err
+	}
+
+	log.Debug("Removed traffic schedulers successfully")
+
+	/* After we successfully remove the scheduler configuration on the OLT device,
+	 * delete the meter id on the KV store.
+	 */
+	err = f.resourceMgr.RemoveMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
+	if err != nil {
+		log.Errorf("Failed to remove meter for onu %d, meter id %d", sq.onuID, KVStoreMeter.MeterId)
+		return err
+	}
+	log.Debugw("Removed-meter-from-KV-store successfully", log.Fields{"MeterId": KVStoreMeter.MeterId, "dir": Direction})
+	return err
+}
+
+// This function allocates tconts and GEM ports for an ONU
+func (f *OpenOltFlowMgr) createTcontGemports(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uni string, uniPort uint32, TpID uint32, UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) (uint32, []uint32, *tp.TechProfile) {
+	var allocIDs []uint32
+	var allgemPortIDs []uint32
+	var gemPortIDs []uint32
+	tpInstanceExists := false
+	var err error
+
+	allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
+	allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
+
+	tpPath := f.getTPpath(intfID, uni, TpID)
+
+	log.Infow("creating-new-tcont-and-gem", log.Fields{"pon": intfID, "onu": onuID, "uni": uniID})
+
+	// Check tech profile instance already exists for derived port name
+	techProfileInstance, _ := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, TpID, tpPath)
+	if techProfileInstance == nil {
+		log.Infow("tp-instance-not-found--creating-new", log.Fields{"path": tpPath})
+		techProfileInstance, err = f.techprofile[intfID].CreateTechProfInstance(ctx, TpID, uni, intfID)
+		if err != nil {
+			// This should not happen, something wrong in KV backend transaction
+			log.Errorw("tp-instance-create-failed", log.Fields{"error": err, "tpID": TpID})
+			return 0, nil, nil
+		}
+		f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID)
+	} else {
+		log.Debugw("Tech-profile-instance-already-exist-for-given port-name", log.Fields{"uni": uni})
+		tpInstanceExists = true
+	}
+	if UsMeterID != 0 {
+		sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
+			uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
+		if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
+			log.Errorw("CreateSchedulerQueues Failed-upstream", log.Fields{"error": err, "meterID": UsMeterID})
+			return 0, nil, nil
+		}
+	}
+	if DsMeterID != 0 {
+		sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
+			uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
+		if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
+			log.Errorw("CreateSchedulerQueues Failed-downstream", log.Fields{"error": err, "meterID": DsMeterID})
+			return 0, nil, nil
+		}
+	}
+
+	allocID := techProfileInstance.UsScheduler.AllocID
+	for _, gem := range techProfileInstance.UpstreamGemPortAttributeList {
+		gemPortIDs = append(gemPortIDs, gem.GemportID)
+	}
+
+	if tpInstanceExists {
+		return allocID, gemPortIDs, techProfileInstance
+	}
+
+	allocIDs = appendUnique(allocIDs, allocID)
+	for _, gemPortID := range gemPortIDs {
+		allgemPortIDs = appendUnique(allgemPortIDs, gemPortID)
+	}
+
+	log.Debugw("Allocated Tcont and GEM ports", log.Fields{"allocIDs": allocIDs, "gemports": allgemPortIDs})
+	// Send Tconts and GEM ports to KV store
+	f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
+	return allocID, gemPortIDs, techProfileInstance
+}
+
+func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
+
+	log.Debugw("Storing allocated Tconts and GEM ports into KV store",
+		log.Fields{"intfId": intfID, "onuId": onuID, "uniId": uniID, "allocID": allocID, "gemPortIDs": gemPortIDs})
+	/* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store  */
+	if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
+		log.Error("Errow while uploading allocID to KV store")
+	}
+	if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
+		log.Error("Errow while uploading GEMports to KV store")
+	}
+	if err := f.resourceMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, gemPortIDs, intfID, onuID, uniID); err != nil {
+		log.Error("Errow while uploading gemtopon map to KV store")
+	}
+	log.Debug("Stored tconts and GEM into KV store successfully")
+	for _, gemPort := range gemPortIDs {
+		f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
+	}
+}
+
+func (f *OpenOltFlowMgr) populateTechProfilePerPonPort() error {
+	var tpCount int
+	for _, techRange := range f.resourceMgr.DevInfo.Ranges {
+		for _, intfID := range techRange.IntfIds {
+			f.techprofile[intfID] = f.resourceMgr.ResourceMgrs[uint32(intfID)].TechProfileMgr
+			tpCount++
+			log.Debugw("Init tech profile done", log.Fields{"intfID": intfID})
+		}
+	}
+	//Make sure we have as many tech_profiles as there are pon ports on the device
+	if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
+		return NewErrInvalidValue(log.Fields{
+			"reason":             "TP count does not match number of PON ports",
+			"tech-profile-count": tpCount,
+			"pon-port-count":     f.resourceMgr.DevInfo.GetPonPorts()}, nil).Log()
+	}
+	log.Infow("Populated techprofile for ponports successfully",
+		log.Fields{"numofTech": tpCount, "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts()})
+	return nil
+}
+
+func (f *OpenOltFlowMgr) addUpstreamDataFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
+	portNo uint32, uplinkClassifier map[string]interface{},
+	uplinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
+	allocID uint32, gemportID uint32) error {
+	uplinkClassifier[PacketTagType] = SingleTag
+	log.Debugw("Adding upstream data flow", log.Fields{"uplinkClassifier": uplinkClassifier, "uplinkAction": uplinkAction})
+	return f.addHSIAFlow(ctx, intfID, onuID, uniID, portNo, uplinkClassifier, uplinkAction,
+		Upstream, logicalFlow, allocID, gemportID)
+	/* TODO: Install Secondary EAP on the subscriber vlan */
+}
+
+func (f *OpenOltFlowMgr) addDownstreamDataFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
+	portNo uint32, downlinkClassifier map[string]interface{},
+	downlinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
+	allocID uint32, gemportID uint32) error {
+	downlinkClassifier[PacketTagType] = DoubleTag
+	log.Debugw("Adding downstream data flow", log.Fields{"downlinkClassifier": downlinkClassifier,
+		"downlinkAction": downlinkAction})
+	// Ignore Downlink trap flow given by core, cannot do anything with this flow */
+	if vlan, exists := downlinkClassifier[VlanVid]; exists {
+		if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
+			if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
+				if uint32(metadata.(uint64)) == MkUniPortNum(intfID, onuID, uniID) {
+					log.Infow("Ignoring DL trap device flow from core", log.Fields{"flow": logicalFlow})
+					return nil
+				}
+			}
+		}
+	}
+
+	/* Already this info available classifier? */
+	downlinkAction[PopVlan] = true
+	// vlan_vid is a uint32.  must be type asserted as such or conversion fails
+	dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
+	if ok {
+		downlinkAction[VlanVid] = dlClVid & 0xfff
+	} else {
+		return NewErrInvalidValue(log.Fields{
+			"reason":  "failed to convert VLANID classifier",
+			"vlan-id": VlanVid}, nil).Log()
+	}
+
+	return f.addHSIAFlow(ctx, intfID, onuID, uniID, portNo, downlinkClassifier, downlinkAction,
+		Downstream, logicalFlow, allocID, gemportID)
+}
+
+func (f *OpenOltFlowMgr) addHSIAFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
+	action map[string]interface{}, direction string, logicalFlow *ofp.OfpFlowStats,
+	allocID uint32, gemPortID uint32) error {
+	/* One of the OLT platform (Broadcom BAL) requires that symmetric
+	   flows require the same flow_id to be used across UL and DL.
+	   Since HSIA flow is the only symmetric flow currently, we need to
+	   re-use the flow_id across both direction. The 'flow_category'
+	   takes priority over flow_cookie to find any available HSIA_FLOW
+	   id for the ONU.
+	*/
+	log.Debugw("Adding HSIA flow", log.Fields{"intfId": intfID, "onuId": onuID, "uniId": uniID, "classifier": classifier,
+		"action": action, "direction": direction, "allocId": allocID, "gemPortId": gemPortID,
+		"logicalFlow": *logicalFlow})
+	var vlanPbit uint32 = 0xff // means no pbit
+	if _, ok := classifier[VlanPcp]; ok {
+		vlanPbit = classifier[VlanPcp].(uint32)
+		log.Debugw("Found pbit in the flow", log.Fields{"VlanPbit": vlanPbit})
+	} else {
+		log.Debugw("pbit-not-found-in-flow", log.Fields{"vlan-pcp": VlanPcp})
+	}
+	flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("flow-already-exists")
+		return nil
+	}
+	flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, HsiaFlow, vlanPbit)
+	if err != nil {
+		return NewErrNotFound("hsia-flow-id", log.Fields{"direction": direction}, err).Log()
+	}
+	classifierProto, err := makeOpenOltClassifierField(classifier)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
+	}
+	log.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(action)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": action}, err).Log()
+	}
+	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
+	networkIntfID, err := getNniIntfID(classifier, action)
+	if err != nil {
+		return NewErrNotFound("nni-interface-id",
+			log.Fields{
+				"classifier": classifier,
+				"action":     action,
+			}, err).Log()
+	}
+	flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
+		OnuId:         int32(onuID),
+		UniId:         int32(uniID),
+		FlowId:        flowID,
+		FlowType:      direction,
+		AllocId:       int32(allocID),
+		NetworkIntfId: int32(networkIntfID),
+		GemportId:     int32(gemPortID),
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(logicalFlow.Priority),
+		Cookie:        logicalFlow.Cookie,
+		PortNo:        portNo}
+	if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
+		return NewErrFlowOp("add", flowID, nil, err).Log()
+	}
+	log.Debug("HSIA flow added to device successfully", log.Fields{"direction": direction})
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &flow, flowStoreCookie, HsiaFlow, flowID, logicalFlow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, flow.AccessIntfId,
+		flow.OnuId,
+		flow.UniId,
+		flow.FlowId /*flowCategory,*/, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", flowID, log.Fields{"flow": flow}, err).Log()
+	}
+	return nil
+}
+
+func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32) error {
+
+	networkIntfID, err := getNniIntfID(classifier, action)
+	if err != nil {
+		return NewErrNotFound("nni-interface-id", log.Fields{
+			"classifier": classifier,
+			"action":     action},
+			err).Log()
+	}
+
+	// Clear the action map
+	for k := range action {
+		delete(action, k)
+	}
+
+	action[TrapToHost] = true
+	classifier[UDPSrc] = uint32(68)
+	classifier[UDPDst] = uint32(67)
+	classifier[PacketTagType] = SingleTag
+	delete(classifier, VlanVid)
+
+	flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("Flow-exists--not-re-adding")
+		return nil
+	}
+
+	flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, DhcpFlow, 0 /*classifier[VLAN_PCP].(uint32)*/)
+
+	if err != nil {
+		return NewErrNotFound("flow", log.Fields{
+			"interface-id": intfID,
+			"gem-port":     gemPortID,
+			"cookie":       flowStoreCookie},
+			err).Log()
+	}
+
+	log.Debugw("Creating UL DHCP flow", log.Fields{"ul_classifier": classifier, "ul_action": action, "uplinkFlowId": flowID})
+
+	classifierProto, err := makeOpenOltClassifierField(classifier)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
+	}
+	log.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(action)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": action}, err).Log()
+	}
+
+	dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
+		OnuId:         int32(onuID),
+		UniId:         int32(uniID),
+		FlowId:        flowID,
+		FlowType:      Upstream,
+		AllocId:       int32(allocID),
+		NetworkIntfId: int32(networkIntfID),
+		GemportId:     int32(gemPortID),
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(logicalFlow.Priority),
+		Cookie:        logicalFlow.Cookie,
+		PortNo:        portNo}
+
+	if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
+		return NewErrFlowOp("add", flowID, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
+	}
+	log.Debug("DHCP UL flow added to device successfully")
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &dhcpFlow, flowStoreCookie, "DHCP", flowID, logicalFlow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, dhcpFlow.AccessIntfId,
+		dhcpFlow.OnuId,
+		dhcpFlow.UniId,
+		dhcpFlow.FlowId, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", dhcpFlow.FlowId, log.Fields{"flow": dhcpFlow}, err).Log()
+	}
+
+	return nil
+}
+
+//addIGMPTrapFlow creates IGMP trap-to-host flow
+func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
+	action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32) error {
+	return f.addUpstreamTrapFlow(ctx, intfID, onuID, uniID, portNo, classifier, action, logicalFlow, allocID, gemPortID, IgmpFlow)
+}
+
+//addUpstreamTrapFlow creates a trap-to-host flow
+func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
+	action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, flowType string) error {
+
+	networkIntfID, err := getNniIntfID(classifier, action)
+	if err != nil {
+		return NewErrNotFound("nni-interface-id", log.Fields{
+			"classifier": classifier,
+			"action":     action},
+			err).Log()
+	}
+
+	// Clear the action map
+	for k := range action {
+		delete(action, k)
+	}
+
+	action[TrapToHost] = true
+	classifier[PacketTagType] = SingleTag
+	delete(classifier, VlanVid)
+
+	flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkIntfID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("Flow-exists-not-re-adding")
+		return nil
+	}
+
+	flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, flowType, 0, 0 /*classifier[VLAN_PCP].(uint32)*/)
+
+	if err != nil {
+		return NewErrNotFound("flow-id", log.Fields{
+			"interface-id": intfID,
+			"oni-id":       onuID,
+			"cookie":       flowStoreCookie,
+			"flow-type":    flowType},
+			err).Log()
+	}
+
+	log.Debugw("Creating upstream trap flow", log.Fields{"ul_classifier": classifier, "ul_action": action, "uplinkFlowId": flowID, "flowType": flowType})
+
+	classifierProto, err := makeOpenOltClassifierField(classifier)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
+	}
+	log.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(action)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": action}, err).Log()
+	}
+
+	flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
+		OnuId:         int32(onuID),
+		UniId:         int32(uniID),
+		FlowId:        flowID,
+		FlowType:      Upstream,
+		AllocId:       int32(allocID),
+		NetworkIntfId: int32(networkIntfID),
+		GemportId:     int32(gemPortID),
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(logicalFlow.Priority),
+		Cookie:        logicalFlow.Cookie,
+		PortNo:        portNo}
+
+	if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
+		return NewErrFlowOp("add", flowID, log.Fields{"flow": flow}, err).Log()
+	}
+	log.Debugf("%s UL flow added to device successfully", flowType)
+
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &flow, flowStoreCookie, flowType, flowID, logicalFlow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, flow.AccessIntfId,
+		flow.OnuId,
+		flow.UniId,
+		flow.FlowId, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", flow.FlowId, log.Fields{"flow": flow}, err).Log()
+	}
+
+	return nil
+}
+
+// Add EAPOL flow to  device with mac, vlanId as classifier for upstream and downstream
+func (f *OpenOltFlowMgr) addEAPOLFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, vlanID uint32) error {
+	log.Debugw("Adding EAPOL to device", log.Fields{"intfId": intfID, "onuId": onuID, "portNo": portNo, "allocId": allocID, "gemPortId": gemPortID, "vlanId": vlanID, "flow": logicalFlow})
+
+	uplinkClassifier := make(map[string]interface{})
+	uplinkAction := make(map[string]interface{})
+
+	// Fill Classfier
+	uplinkClassifier[EthType] = uint32(EapEthType)
+	uplinkClassifier[PacketTagType] = SingleTag
+	uplinkClassifier[VlanVid] = vlanID
+	// Fill action
+	uplinkAction[TrapToHost] = true
+	flowStoreCookie := getFlowStoreCookie(uplinkClassifier, gemPortID)
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("Flow-exists-not-re-adding")
+		return nil
+	}
+	//Add Uplink EAPOL Flow
+	uplinkFlowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, "", 0)
+	if err != nil {
+		return NewErrNotFound("flow-id", log.Fields{
+			"interface-id": intfID,
+			"onu-id":       onuID,
+			"coookie":      flowStoreCookie},
+			err).Log()
+	}
+	log.Debugw("Creating UL EAPOL flow", log.Fields{"ul_classifier": uplinkClassifier, "ul_action": uplinkAction, "uplinkFlowId": uplinkFlowID})
+
+	classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": uplinkClassifier}, err).Log()
+	}
+	log.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(uplinkAction)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": uplinkAction}, err).Log()
+	}
+	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
+	networkIntfID, err := getNniIntfID(classifier, action)
+	if err != nil {
+		return NewErrNotFound("nni-interface-id", log.Fields{
+			"classifier": classifier,
+			"action":     action},
+			err).Log()
+	}
+
+	upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
+		OnuId:         int32(onuID),
+		UniId:         int32(uniID),
+		FlowId:        uplinkFlowID,
+		FlowType:      Upstream,
+		AllocId:       int32(allocID),
+		NetworkIntfId: int32(networkIntfID),
+		GemportId:     int32(gemPortID),
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(logicalFlow.Priority),
+		Cookie:        logicalFlow.Cookie,
+		PortNo:        portNo}
+	if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
+		return NewErrFlowOp("add", uplinkFlowID, log.Fields{"flow": upstreamFlow}, err).Log()
+	}
+	log.Debug("EAPOL UL flow added to device successfully")
+	flowCategory := "EAPOL"
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &upstreamFlow, flowStoreCookie, flowCategory, uplinkFlowID, logicalFlow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, upstreamFlow.AccessIntfId,
+		upstreamFlow.OnuId,
+		upstreamFlow.UniId,
+		upstreamFlow.FlowId,
+		/* lowCategory, */
+		flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", upstreamFlow.FlowId, log.Fields{"flow": upstreamFlow}, err).Log()
+	}
+
+	log.Debugw("Added EAPOL flows to device successfully", log.Fields{"flow": logicalFlow})
+	return nil
+}
+
+func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
+	var classifier openoltpb2.Classifier
+
+	classifier.EthType, _ = classifierInfo[EthType].(uint32)
+	classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
+	if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
+		vid := vlanID & VlanvIDMask
+		if vid != ReservedVlan {
+			classifier.OVid = vid
+		}
+	}
+	if metadata, ok := classifierInfo[Metadata].(uint64); ok {
+		vid := uint32(metadata)
+		if vid != ReservedVlan {
+			classifier.IVid = vid
+		}
+	}
+	// Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
+	if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
+		classifier.OPbits = vlanPcp
+	} else {
+		classifier.OPbits = VlanPCPMask
+	}
+	classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
+	classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
+	classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
+	classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
+	classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
+	if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
+		classifier.PktTagType = pktTagType
+
+		switch pktTagType {
+		case SingleTag:
+		case DoubleTag:
+		case Untagged:
+		default:
+			return nil, NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil).Log()
+		}
+	}
+	return &classifier, nil
+}
+
+func makeOpenOltActionField(actionInfo map[string]interface{}) (*openoltpb2.Action, error) {
+	var actionCmd openoltpb2.ActionCmd
+	var action openoltpb2.Action
+	action.Cmd = &actionCmd
+	if _, ok := actionInfo[PopVlan]; ok {
+		action.OVid = actionInfo[VlanVid].(uint32)
+		action.Cmd.RemoveOuterTag = true
+	} else if _, ok := actionInfo[PushVlan]; ok {
+		action.OVid = actionInfo[VlanVid].(uint32)
+		action.Cmd.AddOuterTag = true
+	} else if _, ok := actionInfo[TrapToHost]; ok {
+		action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
+	} else {
+		return nil, NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil).Log()
+	}
+	return &action, nil
+}
+
+func (f *OpenOltFlowMgr) getTPpath(intfID uint32, uni string, TpID uint32) string {
+	return f.techprofile[intfID].GetTechProfileInstanceKVPath(TpID, uni)
+}
+
+// DeleteTechProfileInstances removes the tech profile instances from persistent storage
+func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, sn string) error {
+	tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
+	uniPortName := fmt.Sprintf("pon-{%d}/onu-{%d}/uni-{%d}", intfID, onuID, uniID)
+	for _, tpID := range tpIDList {
+		if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
+			log.Debugw("Failed-to-delete-tp-instance-from-kv-store", log.Fields{"tp-id": tpID, "uni-port-name": uniPortName})
+			// return err
+			// We should continue to delete tech-profile instances for other TP IDs
+		}
+	}
+	return nil
+}
+
+// DeleteTechProfileInstance removes the tech profile instance from persistent storage
+func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
+	if uniPortName == "" {
+		uniPortName = fmt.Sprintf("pon-{%d}/onu-{%d}/uni-{%d}", intfID, onuID, uniID)
+	}
+	if err := f.techprofile[intfID].DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
+		log.Debugw("Failed-to-delete-tp-instance-from-kv-store", log.Fields{"tp-id": tpID, "uni-port-name": uniPortName})
+		return err
+	}
+	return nil
+}
+
+func getFlowStoreCookie(classifier map[string]interface{}, gemPortID uint32) uint64 {
+	if len(classifier) == 0 { // should never happen
+		log.Error("Invalid classfier object")
+		return 0
+	}
+	log.Debugw("generating flow store cookie", log.Fields{"classifier": classifier, "gemPortID": gemPortID})
+	var jsonData []byte
+	var flowString string
+	var err error
+	// TODO: Do we need to marshall ??
+	if jsonData, err = json.Marshal(classifier); err != nil {
+		log.Error("Failed to encode classifier")
+		return 0
+	}
+	flowString = string(jsonData)
+	if gemPortID != 0 {
+		flowString = fmt.Sprintf("%s%s", string(jsonData), string(gemPortID))
+	}
+	h := md5.New()
+	_, _ = h.Write([]byte(flowString))
+	hash := big.NewInt(0)
+	hash.SetBytes(h.Sum(nil))
+	generatedHash := hash.Uint64()
+	log.Debugw("hash generated", log.Fields{"hash": generatedHash})
+	return generatedHash
+}
+
+func (f *OpenOltFlowMgr) getUpdatedFlowInfo(ctx context.Context, flow *openoltpb2.Flow, flowStoreCookie uint64, flowCategory string, deviceFlowID uint32, logicalFlowID uint64) *[]rsrcMgr.FlowInfo {
+	var flows = []rsrcMgr.FlowInfo{{Flow: flow, FlowCategory: flowCategory, FlowStoreCookie: flowStoreCookie, LogicalFlowID: logicalFlowID}}
+	var intfID uint32
+	/* For flows which trap out of the NNI, the AccessIntfId is invalid
+	   (set to -1). In such cases, we need to refer to the NetworkIntfId .
+	*/
+	if flow.AccessIntfId != -1 {
+		intfID = uint32(flow.AccessIntfId)
+	} else {
+		intfID = uint32(flow.NetworkIntfId)
+	}
+	// Get existing flows matching flowid for given subscriber from KV store
+	existingFlows := f.resourceMgr.GetFlowIDInfo(ctx, intfID, flow.OnuId, flow.UniId, flow.FlowId)
+	if existingFlows != nil {
+		log.Debugw("Flow exists for given flowID, appending it to current flow", log.Fields{"flowID": flow.FlowId})
+		//for _, f := range *existingFlows {
+		//	flows = append(flows, f)
+		//}
+		flows = append(flows, *existingFlows...)
+	}
+	log.Debugw("Updated flows for given flowID and onuid", log.Fields{"updatedflow": flows, "flowid": flow.FlowId, "onu": flow.OnuId})
+	return &flows
+}
+
+//func (f *OpenOltFlowMgr) getUpdatedFlowInfo(flow *openolt_pb2.Flow, flowStoreCookie uint64, flowCategory string) *[]rsrcMgr.FlowInfo {
+//	var flows []rsrcMgr.FlowInfo = []rsrcMgr.FlowInfo{rsrcMgr.FlowInfo{Flow: flow, FlowCategory: flowCategory, FlowStoreCookie: flowStoreCookie}}
+//	var intfId uint32
+//	/* For flows which trap out of the NNI, the AccessIntfId is invalid
+//	   (set to -1). In such cases, we need to refer to the NetworkIntfId .
+//	*/
+//	if flow.AccessIntfId != -1 {
+//		intfId = uint32(flow.AccessIntfId)
+//	} else {
+//		intfId = uint32(flow.NetworkIntfId)
+//	}
+//	// Get existing flows matching flowid for given subscriber from KV store
+//	existingFlows := f.resourceMgr.GetFlowIDInfo(intfId, uint32(flow.OnuId), uint32(flow.UniId), flow.FlowId)
+//	if existingFlows != nil {
+//		log.Debugw("Flow exists for given flowID, appending it to current flow", log.Fields{"flowID": flow.FlowId})
+//		for _, f := range *existingFlows {
+//			flows = append(flows, f)
+//		}
+//	}
+//	log.Debugw("Updated flows for given flowID and onuid", log.Fields{"updatedflow": flows, "flowid": flow.FlowId, "onu": flow.OnuId})
+//	return &flows
+//}
+
+func (f *OpenOltFlowMgr) updateFlowInfoToKVStore(ctx context.Context, intfID int32, onuID int32, uniID int32, flowID uint32, flows *[]rsrcMgr.FlowInfo) error {
+	log.Debugw("Storing flow(s) into KV store", log.Fields{"flows": *flows})
+	if err := f.resourceMgr.UpdateFlowIDInfo(ctx, intfID, onuID, uniID, flowID, flows); err != nil {
+		log.Debug("Error while Storing flow into KV store")
+		return err
+	}
+	log.Info("Stored flow(s) into KV store successfully!")
+	return nil
+}
+
+func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
+
+	var intfID uint32
+	/* For flows which trap out of the NNI, the AccessIntfId is invalid
+	   (set to -1). In such cases, we need to refer to the NetworkIntfId .
+	*/
+	if deviceFlow.AccessIntfId != -1 {
+		intfID = uint32(deviceFlow.AccessIntfId)
+	} else {
+		// REVIST : Why ponport is given as network port?
+		intfID = uint32(deviceFlow.NetworkIntfId)
+	}
+
+	log.Debugw("Sending flow to device via grpc", log.Fields{"flow": *deviceFlow})
+	_, err := f.deviceHandler.Client.FlowAdd(context.Background(), deviceFlow)
+
+	st, _ := status.FromError(err)
+	if st.Code() == codes.AlreadyExists {
+		log.Debug("Flow already exists", log.Fields{"err": err, "deviceFlow": deviceFlow})
+		return nil
+	}
+
+	if err != nil {
+		log.Errorw("Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": deviceFlow})
+		f.resourceMgr.FreeFlowID(ctx, intfID, deviceFlow.OnuId, deviceFlow.UniId, deviceFlow.FlowId)
+		return err
+	}
+	if deviceFlow.GemportId != -1 {
+		// No need to register the flow if it is a trap on nni flow.
+		f.registerFlow(ctx, logicalFlow, deviceFlow)
+	}
+	log.Debugw("Flow added to device successfully ", log.Fields{"flow": *deviceFlow})
+	return nil
+}
+
+func (f *OpenOltFlowMgr) removeFlowFromDevice(deviceFlow *openoltpb2.Flow) error {
+	log.Debugw("Sending flow to device via grpc", log.Fields{"flow": *deviceFlow})
+	_, err := f.deviceHandler.Client.FlowRemove(context.Background(), deviceFlow)
+	if err != nil {
+		if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
+			log.Warnw("Can not remove flow from device since it's unreachable", log.Fields{"err": err, "deviceFlow": deviceFlow})
+			//Assume the flow is removed
+			return nil
+		}
+		log.Errorw("Failed to Remove flow from device", log.Fields{"err": err, "deviceFlow": deviceFlow})
+		return err
+
+	}
+	log.Debugw("Flow removed from device successfully ", log.Fields{"flow": *deviceFlow})
+	return nil
+}
+
+/*func register_flow(deviceFlow *openolt_pb2.Flow, logicalFlow *ofp.OfpFlowStats){
+ //update core flows_proxy : flows_proxy.update('/', flows)
+}
+
+func generateStoredId(flowId uint32, direction string)uint32{
+
+	if direction == Upstream{
+		log.Debug("Upstream flow shifting flowid")
+		return ((0x1 << 15) | flowId)
+	}else if direction == Downstream{
+		log.Debug("Downstream flow not shifting flowid")
+		return flowId
+	}else{
+		log.Errorw("Unrecognized direction",log.Fields{"direction": direction})
+		return flowId
+	}
+}
+
+*/
+
+func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
+
+	classifierInfo := make(map[string]interface{})
+	actionInfo := make(map[string]interface{})
+
+	classifierInfo[EthType] = uint32(LldpEthType)
+	classifierInfo[PacketTagType] = Untagged
+	actionInfo[TrapToHost] = true
+
+	// LLDP flow is installed to trap LLDP packets on the NNI port.
+	// We manage flow_id resource pool on per PON port basis.
+	// Since this situation is tricky, as a hack, we pass the NNI port
+	// index (network_intf_id) as PON port Index for the flow_id resource
+	// pool. Also, there is no ONU Id available for trapping LLDP packets
+	// on NNI port, use onu_id as -1 (invalid)
+	// ****************** CAVEAT *******************
+	// This logic works if the NNI Port Id falls within the same valid
+	// range of PON Port Ids. If this doesn't work for some OLT Vendor
+	// we need to have a re-look at this.
+	// *********************************************
+
+	var onuID = -1
+	var uniID = -1
+	var gemPortID = -1
+
+	networkInterfaceID, err := IntfIDFromNniPortNum(portNo)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
+	}
+	var flowStoreCookie = getFlowStoreCookie(classifierInfo, uint32(0))
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("Flow-exists--not-re-adding")
+		return nil
+	}
+	flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0)
+
+	if err != nil {
+		return NewErrNotFound("flow-id", log.Fields{
+			"interface-id": networkInterfaceID,
+			"onu-id":       onuID,
+			"uni-id":       uniID,
+			"gem-port-id":  gemPortID,
+			"cookie":       flowStoreCookie},
+			err).Log()
+	}
+	classifierProto, err := makeOpenOltClassifierField(classifierInfo)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifierInfo}, err).Log()
+	}
+	log.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(actionInfo)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": actionInfo}, err).Log()
+	}
+	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
+
+	downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
+		OnuId:         int32(onuID), // OnuId not required
+		UniId:         int32(uniID), // UniId not used
+		FlowId:        flowID,
+		FlowType:      Downstream,
+		NetworkIntfId: int32(networkInterfaceID),
+		GemportId:     int32(gemPortID),
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(flow.Priority),
+		Cookie:        flow.Cookie,
+		PortNo:        portNo}
+	if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
+		return NewErrFlowOp("add", flowID, log.Fields{"flow": downstreamflow}, err).Log()
+	}
+	log.Debug("LLDP trap on NNI flow added to device successfully")
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &downstreamflow, flowStoreCookie, "", flowID, flow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, int32(networkInterfaceID),
+		int32(onuID),
+		int32(uniID),
+		flowID, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", flowID, log.Fields{"flow": downstreamflow}, err).Log()
+	}
+	return nil
+}
+
+func getUniPortPath(intfID uint32, onuID int32, uniID int32) string {
+	return fmt.Sprintf("pon-{%d}/onu-{%d}/uni-{%d}", intfID, onuID, uniID)
+}
+
+//getOnuChildDevice to fetch onu
+func (f *OpenOltFlowMgr) getOnuChildDevice(intfID uint32, onuID uint32) (*voltha.Device, error) {
+	log.Debugw("GetChildDevice", log.Fields{"pon port": intfID, "onuId": onuID})
+	parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
+	onuDevice, err := f.deviceHandler.GetChildDevice(parentPortNo, onuID)
+	if err != nil {
+		return nil, NewErrNotFound("onu", log.Fields{
+			"interface-id": parentPortNo,
+			"onu-id":       onuID},
+			err).Log()
+	}
+	log.Debugw("Successfully received child device from core", log.Fields{"child_device": *onuDevice})
+	return onuDevice, nil
+}
+
+func findNextFlow(flow *ofp.OfpFlowStats) *ofp.OfpFlowStats {
+	log.Info("unimplemented flow : %v", flow)
+	return nil
+}
+
+func (f *OpenOltFlowMgr) clearFlowsAndSchedulerForLogicalPort(childDevice *voltha.Device, logicalPort *voltha.LogicalPort) {
+	log.Info("unimplemented device %v, logicalport %v", childDevice, logicalPort)
+}
+
+func (f *OpenOltFlowMgr) decodeStoredID(id uint64) (uint64, string) {
+	if id>>15 == 0x1 {
+		return id & 0x7fff, Upstream
+	}
+	return id, Downstream
+}
+
+func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
+	onuDevice, err := f.getOnuChildDevice(intfID, onuID)
+	if err != nil {
+		log.Errorw("error fetching child device from core", log.Fields{"onuId": onuID})
+		return err
+	}
+
+	delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpPath: tpPath, GemPortId: gemPortID}
+	log.Debugw("sending gem port delete to openonu adapter", log.Fields{"msg": *delGemPortMsg})
+	if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(context.Background(),
+		delGemPortMsg,
+		ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
+		f.deviceHandler.deviceType,
+		onuDevice.Type,
+		onuDevice.Id,
+		onuDevice.ProxyAddress.DeviceId, ""); sendErr != nil {
+		log.Errorw("failure sending del gem port to onu adapter", log.Fields{"fromAdapter": f.deviceHandler.deviceType,
+			"toAdapter": onuDevice.Type, "onuId": onuDevice.Id,
+			"proxyDeviceId": onuDevice.ProxyAddress.DeviceId})
+		return sendErr
+	}
+	log.Debugw("success sending del gem port to onu adapter", log.Fields{"msg": delGemPortMsg})
+	return nil
+}
+
+func (f *OpenOltFlowMgr) sendDeleteTcontToChild(intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
+	onuDevice, err := f.getOnuChildDevice(intfID, onuID)
+	if err != nil {
+		log.Errorw("error fetching child device from core", log.Fields{"onuId": onuID})
+		return err
+	}
+
+	delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpPath: tpPath, AllocId: allocID}
+	log.Debugw("sending tcont delete to openonu adapter", log.Fields{"msg": *delTcontMsg})
+	if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(context.Background(),
+		delTcontMsg,
+		ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
+		f.deviceHandler.deviceType,
+		onuDevice.Type,
+		onuDevice.Id,
+		onuDevice.ProxyAddress.DeviceId, ""); sendErr != nil {
+		log.Errorw("failure sending del tcont to onu adapter", log.Fields{"fromAdapter": f.deviceHandler.deviceType,
+			"toAdapter": onuDevice.Type, "onuId": onuDevice.Id,
+			"proxyDeviceId": onuDevice.ProxyAddress.DeviceId})
+		return sendErr
+	}
+	log.Debugw("success sending del tcont to onu adapter", log.Fields{"msg": delTcontMsg})
+	return nil
+}
+
+func (f *OpenOltFlowMgr) deletePendingFlows(Intf uint32, onuID int32, uniID int32) {
+	pnFlDelKey := pendingFlowDeleteKey{Intf, uint32(onuID), uint32(uniID)}
+	if val, ok := f.pendingFlowDelete.Load(pnFlDelKey); ok {
+		if val.(int) > 0 {
+			pnFlDels := val.(int) - 1
+			if pnFlDels > 0 {
+				log.Debugw("flow delete succeeded, more pending",
+					log.Fields{"intf": Intf, "onuID": onuID, "uniID": uniID, "currPendingFlowCnt": pnFlDels})
+				f.pendingFlowDelete.Store(pnFlDelKey, pnFlDels)
+			} else {
+				log.Debugw("all pending flow deletes handled, removing entry from map",
+					log.Fields{"intf": Intf, "onuID": onuID, "uniID": uniID})
+				f.pendingFlowDelete.Delete(pnFlDelKey)
+			}
+		}
+	} else {
+		log.Debugw("no pending delete flows found",
+			log.Fields{"intf": Intf, "onuID": onuID, "uniID": uniID})
+
+	}
+
+}
+
+// Once the gemport is released for a given onu, it also has to be cleared from local cache
+// which was used for deriving the gemport->logicalPortNo during packet-in.
+// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
+// is conveyed to ONOS during packet-in OF message.
+func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(intfID uint32, onuID uint32, gemPortID uint32) {
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+	onugem := f.onuGemInfo[intfID]
+	for i, onu := range onugem {
+		if onu.OnuID == onuID {
+			for j, gem := range onu.GemPorts {
+				// If the gemport is found, delete it from local cache.
+				if gem == gemPortID {
+					onu.GemPorts = append(onu.GemPorts[:j], onu.GemPorts[j+1:]...)
+					onugem[i] = onu
+					log.Debugw("removed gemport from local cache",
+						log.Fields{"intfID": intfID, "onuID": onuID, "deletedGemPortID": gemPortID, "gemPorts": onu.GemPorts})
+					break
+				}
+			}
+			break
+		}
+	}
+}
+
+//clearResources clears pon resources in kv store and the device
+func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, Intf uint32, onuID int32, uniID int32,
+	gemPortID int32, flowID uint32, flowDirection string,
+	portNum uint32, updatedFlows []rsrcMgr.FlowInfo) error {
+
+	tpID, err := getTpIDFromFlow(flow)
+	if err != nil {
+		log.Error("metadata-is-not-present-invalid-flow-to-process", log.Fields{"pon": Intf, "onuID": onuID, "uniID": uniID})
+		return err
+	}
+
+	if len(updatedFlows) >= 0 {
+		// There are still flows referencing the same flow_id.
+		// So the flow should not be freed yet.
+		// For ex: Case of HSIA where same flow is shared
+		// between DS and US.
+		f.updateFlowInfoToKVStore(ctx, int32(Intf), int32(onuID), int32(uniID), flowID, &updatedFlows)
+		if len(updatedFlows) == 0 {
+			// Do this for subscriber flows only (not trap from NNI flows)
+			if onuID != -1 && uniID != -1 {
+				pnFlDelKey := pendingFlowDeleteKey{Intf, uint32(onuID), uint32(uniID)}
+				if val, ok := f.pendingFlowDelete.Load(pnFlDelKey); !ok {
+					log.Debugw("creating entry for pending flow delete",
+						log.Fields{"intf": Intf, "onuID": onuID, "uniID": uniID})
+					f.pendingFlowDelete.Store(pnFlDelKey, 1)
+				} else {
+					pnFlDels := val.(int) + 1
+					log.Debugw("updating flow delete entry",
+						log.Fields{"intf": Intf, "onuID": onuID, "uniID": uniID, "currPendingFlowCnt": pnFlDels})
+					f.pendingFlowDelete.Store(pnFlDelKey, pnFlDels)
+				}
+
+				defer f.deletePendingFlows(Intf, onuID, uniID)
+			}
+
+			log.Debugw("Releasing flow Id to resource manager", log.Fields{"Intf": Intf, "onuId": onuID, "uniId": uniID, "flowId": flowID})
+			f.resourceMgr.FreeFlowID(ctx, Intf, int32(onuID), int32(uniID), flowID)
+
+			uni := getUniPortPath(Intf, onuID, uniID)
+			tpPath := f.getTPpath(Intf, uni, tpID)
+			log.Debugw("Getting-techprofile-instance-for-subscriber", log.Fields{"TP-PATH": tpPath})
+			techprofileInst, err := f.techprofile[Intf].GetTPInstanceFromKVStore(ctx, tpID, tpPath)
+			if err != nil { // This should not happen, something wrong in KV backend transaction
+				log.Errorw("Error in fetching tech profile instance from KV store", log.Fields{"tpID": 20, "path": tpPath})
+				return err
+			}
+			if techprofileInst == nil {
+				log.Errorw("Tech-profile-instance-does-not-exist-in-KV Store", log.Fields{"tpPath": tpPath})
+				return err
+			}
+
+			gemPK := gemPortKey{Intf, uint32(gemPortID)}
+			if f.isGemPortUsedByAnotherFlow(gemPK) {
+				flowIDs := f.flowsUsedByGemPort[gemPK]
+				for i, flowIDinMap := range flowIDs {
+					if flowIDinMap == flowID {
+						flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
+						// everytime flowsUsedByGemPort cache is updated the same should be updated
+						// in kv store by calling UpdateFlowIDsForGem
+						f.flowsUsedByGemPort[gemPK] = flowIDs
+						f.resourceMgr.UpdateFlowIDsForGem(ctx, Intf, uint32(gemPortID), flowIDs)
+						break
+					}
+				}
+				log.Debugw("Gem port id is still used by other flows", log.Fields{"gemPortID": gemPortID, "usedByFlows": flowIDs})
+				return nil
+			}
+			log.Debugf("Gem port id %d is not used by another flow - releasing the gem port", gemPortID)
+			f.resourceMgr.RemoveGemPortIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
+			// TODO: The TrafficQueue corresponding to this gem-port also should be removed immediately.
+			// But it is anyway eventually  removed later when the TechProfile is freed, so not a big issue for now.
+			f.resourceMgr.RemoveGEMportPonportToOnuMapOnKVStore(ctx, uint32(gemPortID), Intf)
+			f.deleteGemPortFromLocalCache(Intf, uint32(onuID), uint32(gemPortID))
+			f.onuIdsLock.Lock()
+			//everytime an entry is deleted from flowsUsedByGemPort cache, the same should be updated in kv as well
+			// by calling DeleteFlowIDsForGem
+			delete(f.flowsUsedByGemPort, gemPK)
+			f.resourceMgr.DeleteFlowIDsForGem(ctx, Intf, uint32(gemPortID))
+			f.resourceMgr.FreeGemPortID(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
+			f.onuIdsLock.Unlock()
+			// Delete the gem port on the ONU.
+			if err := f.sendDeleteGemPortToChild(Intf, uint32(onuID), uint32(uniID), uint32(gemPortID), tpPath); err != nil {
+				log.Errorw("error processing delete gem-port towards onu",
+					log.Fields{"err": err, "pon": Intf, "onuID": onuID, "uniID": uniID, "gemPortId": gemPortID})
+			}
+
+			ok, _ := f.isTechProfileUsedByAnotherGem(ctx, Intf, uint32(onuID), uint32(uniID), tpID, techprofileInst, uint32(gemPortID))
+			if !ok {
+				f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID)
+				f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst})
+				f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst})
+				f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID)
+				f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID)
+				// Delete the TCONT on the ONU.
+				if err := f.sendDeleteTcontToChild(Intf, uint32(onuID), uint32(uniID), uint32(techprofileInst.UsScheduler.AllocID), tpPath); err != nil {
+					log.Errorw("error processing delete tcont towards onu",
+						log.Fields{"pon": Intf, "onuID": onuID, "uniID": uniID, "allocId": techprofileInst.UsScheduler.AllocID})
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// nolint: gocyclo
+func (f *OpenOltFlowMgr) clearFlowFromResourceManager(ctx context.Context, flow *ofp.OfpFlowStats, flowDirection string) {
+
+	log.Debugw("clearFlowFromResourceManager", log.Fields{"flowDirection": flowDirection, "flow": *flow})
+
+	if flowDirection == Multicast {
+		f.clearMulticastFlowFromResourceManager(ctx, flow)
+		return
+	}
+
+	var updatedFlows []rsrcMgr.FlowInfo
+	classifierInfo := make(map[string]interface{})
+
+	portNum, Intf, onu, uni, inPort, ethType, err := FlowExtractInfo(flow, flowDirection)
+	if err != nil {
+		log.Error(err)
+		return
+	}
+
+	onuID := int32(onu)
+	uniID := int32(uni)
+
+	for _, field := range flows.GetOfbFields(flow) {
+		if field.Type == flows.IP_PROTO {
+			classifierInfo[IPProto] = field.GetIpProto()
+			log.Debug("field-type-ip-proto", log.Fields{"classifierInfo[IP_PROTO]": classifierInfo[IPProto].(uint32)})
+		}
+	}
+	log.Debugw("Extracted access info from flow to be deleted",
+		log.Fields{"ponIntf": Intf, "onuID": onuID, "uniID": uniID})
+
+	if ethType == LldpEthType || ((classifierInfo[IPProto] == IPProtoDhcp) && (flowDirection == "downstream")) {
+		onuID = -1
+		uniID = -1
+		log.Debug("Trap on nni flow set oni, uni to -1")
+		Intf, err = IntfIDFromNniPortNum(inPort)
+		if err != nil {
+			log.Errorw("invalid-in-port-number",
+				log.Fields{
+					"port-number": inPort,
+					"error":       err})
+			return
+		}
+	}
+	flowIds := f.resourceMgr.GetCurrentFlowIDsForOnu(ctx, Intf, onuID, uniID)
+	for _, flowID := range flowIds {
+		flowInfo := f.resourceMgr.GetFlowIDInfo(ctx, Intf, onuID, uniID, flowID)
+		if flowInfo == nil {
+			log.Debugw("No FlowInfo found found in KV store",
+				log.Fields{"Intf": Intf, "onuID": onuID, "uniID": uniID, "flowID": flowID})
+			return
+		}
+		updatedFlows = nil
+		for _, flow := range *flowInfo {
+			updatedFlows = append(updatedFlows, flow)
+		}
+
+		for i, storedFlow := range updatedFlows {
+			if flow.Id == storedFlow.LogicalFlowID {
+				removeFlowMessage := openoltpb2.Flow{FlowId: storedFlow.Flow.FlowId, FlowType: storedFlow.Flow.FlowType}
+				log.Debugw("Flow to be deleted", log.Fields{"flow": storedFlow})
+				// DKB
+				if err = f.removeFlowFromDevice(&removeFlowMessage); err != nil {
+					log.Errorw("failed-to-remove-flow", log.Fields{"error": err})
+					return
+				}
+				log.Debug("Flow removed from device successfully")
+				//Remove the Flow from FlowInfo
+				updatedFlows = append(updatedFlows[:i], updatedFlows[i+1:]...)
+				if err = f.clearResources(ctx, flow, Intf, onuID, uniID, storedFlow.Flow.GemportId,
+					flowID, flowDirection, portNum, updatedFlows); err != nil {
+					log.Error("Failed to clear resources for flow", log.Fields{"flow": storedFlow})
+					return
+				}
+			}
+		}
+	}
+}
+
+//clearMulticastFlowFromResourceManager  removes a multicast flow from the KV store and
+// clears resources reserved for this multicast flow
+func (f *OpenOltFlowMgr) clearMulticastFlowFromResourceManager(ctx context.Context, flow *ofp.OfpFlowStats) {
+	classifierInfo := make(map[string]interface{})
+	formulateClassifierInfoFromFlow(classifierInfo, flow)
+	inPort, err := f.getInPortOfMulticastFlow(ctx, classifierInfo)
+
+	if err != nil {
+		log.Warnw("No inPort found. Cannot release resources of the multicast flow.", log.Fields{"flowId:": flow.Id})
+		return
+	}
+
+	networkInterfaceID, err := IntfIDFromNniPortNum(inPort)
+	if err != nil {
+		// DKB
+		log.Errorw("invalid-in-port-number",
+			log.Fields{
+				"port-number": inPort,
+				"error":       err})
+		return
+	}
+	var onuID = int32(NoneOnuID)
+	var uniID = int32(NoneUniID)
+	var flowID uint32
+	var updatedFlows []rsrcMgr.FlowInfo
+
+	flowIds := f.resourceMgr.GetCurrentFlowIDsForOnu(ctx, networkInterfaceID, onuID, uniID)
+
+	for _, flowID = range flowIds {
+		flowInfo := f.resourceMgr.GetFlowIDInfo(ctx, networkInterfaceID, onuID, uniID, flowID)
+		if flowInfo == nil {
+			log.Debugw("No multicast FlowInfo found in the KV store",
+				log.Fields{"Intf": networkInterfaceID, "onuID": onuID, "uniID": uniID, "flowID": flowID})
+			continue
+		}
+		updatedFlows = nil
+		for _, flow := range *flowInfo {
+			updatedFlows = append(updatedFlows, flow)
+		}
+		for i, storedFlow := range updatedFlows {
+			if flow.Id == storedFlow.LogicalFlowID {
+				removeFlowMessage := openoltpb2.Flow{FlowId: storedFlow.Flow.FlowId, FlowType: storedFlow.Flow.FlowType}
+				log.Debugw("Multicast flow to be deleted", log.Fields{"flow": storedFlow})
+				//remove from device
+				if err := f.removeFlowFromDevice(&removeFlowMessage); err != nil {
+					// DKB
+					log.Errorw("failed-to-remove-multicast-flow",
+						log.Fields{
+							"flow-id": flow.Id,
+							"error":   err})
+					return
+				}
+				log.Debugw("Multicast flow removed from device successfully", log.Fields{"flowId": flow.Id})
+				//Remove the Flow from FlowInfo
+				updatedFlows = append(updatedFlows[:i], updatedFlows[i+1:]...)
+				if err := f.updateFlowInfoToKVStore(ctx, int32(networkInterfaceID), NoneOnuID, NoneUniID, flowID, &updatedFlows); err != nil {
+					log.Error("Failed to delete multicast flow from the KV store", log.Fields{"flow": storedFlow, "err": err})
+					return
+				}
+				//release flow id
+				log.Debugw("Releasing multicast flow id", log.Fields{"flowId": flowID, "interfaceID": networkInterfaceID})
+				f.resourceMgr.FreeFlowID(ctx, uint32(networkInterfaceID), NoneOnuID, NoneUniID, flowID)
+			}
+		}
+	}
+}
+
+//RemoveFlow removes the flow from the device
+func (f *OpenOltFlowMgr) RemoveFlow(ctx context.Context, flow *ofp.OfpFlowStats) {
+	log.Debugw("Removing Flow", log.Fields{"flow": flow})
+	var direction string
+	actionInfo := make(map[string]interface{})
+
+	for _, action := range flows.GetActions(flow) {
+		if action.Type == flows.OUTPUT {
+			if out := action.GetOutput(); out != nil {
+				actionInfo[Output] = out.GetPort()
+				log.Debugw("action-type-output", log.Fields{"out_port": actionInfo[Output].(uint32)})
+			} else {
+				log.Error("Invalid output port in action")
+				return
+			}
+		}
+	}
+
+	if flows.HasGroup(flow) {
+		direction = Multicast
+	} else if IsUpstream(actionInfo[Output].(uint32)) {
+		direction = Upstream
+	} else {
+		direction = Downstream
+	}
+	f.clearFlowFromResourceManager(ctx, flow, direction) //TODO: Take care of the limitations
+
+	return
+}
+
+func (f *OpenOltFlowMgr) waitForFlowDeletesToCompleteForOnu(ctx context.Context, intfID uint32, onuID uint32,
+	uniID uint32, ch chan bool) {
+	pnFlDelKey := pendingFlowDeleteKey{intfID, onuID, uniID}
+	for {
+		select {
+		case <-time.After(20 * time.Millisecond):
+			if flowDelRefCnt, ok := f.pendingFlowDelete.Load(pnFlDelKey); !ok || flowDelRefCnt == 0 {
+				log.Debug("pending flow deletes completed")
+				ch <- true
+				return
+			}
+		case <-ctx.Done():
+			log.Error("flow delete wait handler routine canceled")
+			return
+		}
+	}
+}
+
+//isIgmpTrapDownstreamFlow return true if the flow is a downsteam IGMP trap-to-host flow; false otherwise
+func isIgmpTrapDownstreamFlow(classifierInfo map[string]interface{}) bool {
+	if portType := IntfIDToPortTypeName(classifierInfo[InPort].(uint32)); portType == voltha.Port_ETHERNET_NNI {
+		if ethType, ok := classifierInfo[EthType]; ok {
+			if ethType.(uint32) == IPv4EthType {
+				if ipProto, ok := classifierInfo[IPProto]; ok {
+					if ipProto.(uint32) == IgmpProto {
+						return true
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+
+// AddFlow add flow to device
+// nolint: gocyclo
+func (f *OpenOltFlowMgr) AddFlow(ctx context.Context, flow *ofp.OfpFlowStats, flowMetadata *voltha.FlowMetadata) {
+	classifierInfo := make(map[string]interface{})
+	actionInfo := make(map[string]interface{})
+	var UsMeterID uint32
+	var DsMeterID uint32
+
+	log.Debug("Adding Flow", log.Fields{"flow": flow, "flowMetadata": flowMetadata})
+	formulateClassifierInfoFromFlow(classifierInfo, flow)
+
+	err := formulateActionInfoFromFlow(actionInfo, classifierInfo, flow)
+	if err != nil {
+		// Error logging is already done in the called function
+		// So just return in case of error
+		return
+	}
+
+	if flows.HasGroup(flow) {
+		// handle multicast flow
+		f.handleFlowWithGroup(ctx, actionInfo, classifierInfo, flow)
+		return
+	}
+
+	/* Controller bound trap flows */
+	err = formulateControllerBoundTrapFlowInfo(actionInfo, classifierInfo, flow)
+	if err != nil {
+		// error if any, already logged in the called function
+		return
+	}
+
+	log.Infow("Flow ports", log.Fields{"classifierInfo_inport": classifierInfo[InPort], "action_output": actionInfo[Output]})
+	portNo, intfID, onuID, uniID := ExtractAccessFromFlow(classifierInfo[InPort].(uint32), actionInfo[Output].(uint32))
+
+	if ethType, ok := classifierInfo[EthType]; ok {
+		if ethType.(uint32) == LldpEthType {
+			log.Info("Adding LLDP flow")
+			f.addLLDPFlow(ctx, flow, portNo)
+			return
+		}
+	}
+	if ipProto, ok := classifierInfo[IPProto]; ok {
+		if ipProto.(uint32) == IPProtoDhcp {
+			if udpSrc, ok := classifierInfo[UDPSrc]; ok {
+				if udpSrc.(uint32) == uint32(67) || udpSrc.(uint32) == uint32(546) {
+					log.Debug("trap-dhcp-from-nni-flow")
+					f.addDHCPTrapFlowOnNNI(ctx, flow, classifierInfo, portNo)
+					return
+				}
+			}
+		}
+	}
+	if isIgmpTrapDownstreamFlow(classifierInfo) {
+		log.Debug("trap-igmp-from-nni-flow")
+		f.addIgmpTrapFlowOnNNI(ctx, flow, classifierInfo, portNo)
+		return
+	}
+
+	f.deviceHandler.AddUniPortToOnu(intfID, onuID, portNo)
+	f.resourceMgr.AddUniPortToOnuInfo(ctx, intfID, onuID, portNo)
+
+	TpID, err := getTpIDFromFlow(flow)
+	if err != nil {
+		log.Error("metadata-is-not-present-invalid-flow-to-process", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
+		return
+	}
+	log.Debugw("TPID for this subcriber", log.Fields{"TpId": TpID, "pon": intfID, "onuID": onuID, "uniID": uniID})
+	if IsUpstream(actionInfo[Output].(uint32)) {
+		UsMeterID = flows.GetMeterIdFromFlow(flow)
+		log.Debugw("Upstream-flow-meter-id", log.Fields{"UsMeterID": UsMeterID})
+	} else {
+		DsMeterID = flows.GetMeterIdFromFlow(flow)
+		log.Debugw("Downstream-flow-meter-id", log.Fields{"DsMeterID": DsMeterID})
+
+	}
+
+	pnFlDelKey := pendingFlowDeleteKey{intfID, onuID, uniID}
+	if _, ok := f.pendingFlowDelete.Load(pnFlDelKey); !ok {
+		log.Debugw("no pending flows found, going ahead with flow install", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
+		f.divideAndAddFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, uint32(TpID), UsMeterID, DsMeterID, flowMetadata)
+	} else {
+		pendingFlowDelComplete := make(chan bool)
+		go f.waitForFlowDeletesToCompleteForOnu(ctx, intfID, onuID, uniID, pendingFlowDelComplete)
+		select {
+		case <-pendingFlowDelComplete:
+			log.Debugw("all pending flow deletes completed", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
+			f.divideAndAddFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, uint32(TpID), UsMeterID, DsMeterID, flowMetadata)
+
+		case <-time.After(10 * time.Second):
+			log.Errorw("pending flow deletes not completed after timeout", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
+		}
+	}
+}
+
+// handleFlowWithGroup adds multicast flow to the device.
+func (f *OpenOltFlowMgr) handleFlowWithGroup(ctx context.Context, actionInfo, classifierInfo map[string]interface{}, flow *ofp.OfpFlowStats) error {
+	classifierInfo[PacketTagType] = DoubleTag
+	log.Debugw("add-multicast-flow", log.Fields{"classifierInfo": classifierInfo, "actionInfo": actionInfo})
+
+	inPort, err := f.getInPortOfMulticastFlow(ctx, classifierInfo)
+	if err != nil {
+		return NewErrNotFound("multicast-in-port", log.Fields{"classifier": classifierInfo}, err).Log()
+	}
+	//replace ipDst with ethDst
+	if ipv4Dst, ok := classifierInfo[Ipv4Dst]; ok &&
+		flows.IsMulticastIp(ipv4Dst.(uint32)) {
+		// replace ipv4_dst classifier with eth_dst
+		multicastMac := flows.ConvertToMulticastMacBytes(ipv4Dst.(uint32))
+		delete(classifierInfo, Ipv4Dst)
+		delete(classifierInfo, EthType)
+		classifierInfo[EthDst] = multicastMac
+		log.Debugw("multicast-ip-to-mac-conversion-success", log.Fields{"ip:": ipv4Dst.(uint32), "mac:": multicastMac})
+	}
+
+	onuID := NoneOnuID
+	uniID := NoneUniID
+	gemPortID := NoneGemPortID
+
+	networkInterfaceID, err := IntfIDFromNniPortNum(inPort)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"nni-in-port-number": inPort}, err).Log()
+	}
+
+	flowStoreCookie := getFlowStoreCookie(classifierInfo, uint32(0))
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debugw("multicast-flow-exists-not-re-adding", log.Fields{"classifierInfo": classifierInfo})
+		return nil
+	}
+	flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0, 0)
+	if err != nil {
+		return NewErrNotFound("multicast-flow-id", log.Fields{
+			"interface-id": networkInterfaceID,
+			"onu-id":       onuID,
+			"uni-id":       uniID,
+			"gem-port-id":  gemPortID,
+			"cookie":       flowStoreCookie},
+			err).Log()
+	}
+	classifierProto, err := makeOpenOltClassifierField(classifierInfo)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifierInfo}, err).Log()
+	}
+	groupID := actionInfo[GroupID].(uint32)
+	multicastFlow := openoltpb2.Flow{
+		FlowId:        flowID,
+		FlowType:      Multicast,
+		NetworkIntfId: int32(networkInterfaceID),
+		GroupId:       groupID,
+		Classifier:    classifierProto,
+		Priority:      int32(flow.Priority),
+		Cookie:        flow.Cookie}
+
+	if err = f.addFlowToDevice(ctx, flow, &multicastFlow); err != nil {
+		return NewErrFlowOp("add", flowID, log.Fields{"flow": multicastFlow}, err).Log()
+	}
+	log.Debug("multicast flow added to device successfully")
+	//get cached group
+	group, _, err := f.GetFlowGroupFromKVStore(ctx, groupID, true)
+	if err == nil {
+		//calling groupAdd to set group members after multicast flow creation
+		if f.ModifyGroup(ctx, group) {
+			//cached group can be removed now
+			f.resourceMgr.RemoveFlowGroupFromKVStore(ctx, groupID, true)
+		}
+	}
+
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &multicastFlow, flowStoreCookie, MulticastFlow, flowID, flow.Id)
+	if err = f.updateFlowInfoToKVStore(ctx, int32(networkInterfaceID),
+		int32(onuID),
+		int32(uniID),
+		flowID, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", flowID, log.Fields{"flow": multicastFlow}, err).Log()
+	}
+	return nil
+}
+
+//getInPortOfMulticastFlow return inPort criterion if exists; returns NNI interface of the device otherwise
+func (f *OpenOltFlowMgr) getInPortOfMulticastFlow(ctx context.Context, classifierInfo map[string]interface{}) (uint32, error) {
+	if _, ok := classifierInfo[InPort]; ok {
+		return classifierInfo[InPort].(uint32), nil
+	}
+	// find first NNI port of the device
+	nniPorts, e := f.resourceMgr.GetNNIFromKVStore(ctx)
+	if e == nil && len(nniPorts) > 0 {
+		return nniPorts[0], nil
+	}
+	return 0, NewErrNotFound("nni-port", nil, e).Log()
+}
+
+// AddGroup add or update the group
+func (f *OpenOltFlowMgr) AddGroup(ctx context.Context, group *ofp.OfpGroupEntry) {
+	log.Infow("add-group", log.Fields{"group": group})
+	if group == nil {
+		log.Warn("skipping nil group")
+		return
+	}
+
+	groupToOlt := openoltpb2.Group{
+		GroupId: group.Desc.GroupId,
+		Command: openoltpb2.Group_SET_MEMBERS,
+		Action:  f.buildGroupAction(),
+	}
+
+	log.Debugw("Sending group to device", log.Fields{"groupToOlt": groupToOlt})
+	_, err := f.deviceHandler.Client.PerformGroupOperation(ctx, &groupToOlt)
+	if err != nil {
+		log.Errorw("add-group operation failed", log.Fields{"err": err, "groupToOlt": groupToOlt})
+		return
+	}
+	// group members not created yet. So let's store the group
+	if err := f.resourceMgr.AddFlowGroupToKVStore(ctx, group, true); err != nil {
+		log.Errorw("Group cannot be stored in KV store", log.Fields{"groupId": group.Desc.GroupId, "err": err})
+	} else {
+		log.Debugw("add-group operation performed on the device successfully ", log.Fields{"groupToOlt": groupToOlt})
+	}
+}
+
+//buildGroupAction creates and returns a group action
+func (f *OpenOltFlowMgr) buildGroupAction() *openoltpb2.Action {
+	var actionCmd openoltpb2.ActionCmd
+	var action openoltpb2.Action
+	action.Cmd = &actionCmd
+	//pop outer vlan
+	action.Cmd.RemoveOuterTag = true
+	return &action
+}
+
+// ModifyGroup updates the group
+func (f *OpenOltFlowMgr) ModifyGroup(ctx context.Context, group *ofp.OfpGroupEntry) bool {
+	log.Infow("modify-group", log.Fields{"group": group})
+	if group == nil || group.Desc == nil {
+		log.Warn("cannot modify group; group is nil")
+		return false
+	}
+
+	new := f.buildGroup(group.Desc.GroupId, group.Desc.Buckets)
+	//get existing members of the group
+	val, groupExists, err := f.GetFlowGroupFromKVStore(ctx, group.Desc.GroupId, false)
+
+	if err != nil {
+		log.Errorw("Failed to retrieve the group from the store. Cannot modify group.",
+			log.Fields{"groupId": group.Desc.GroupId, "err": err})
+		return false
+	}
+
+	var current *openoltpb2.Group // represents the group on the device
+	if groupExists {
+		// group already exists
+		current = f.buildGroup(group.Desc.GroupId, val.Desc.GetBuckets())
+		log.Debugw("modify-group: group exists.", log.Fields{"group on the device": val, "new": group})
+	} else {
+		current = f.buildGroup(group.Desc.GroupId, nil)
+	}
+
+	log.Debugw("modify-group: comparing current and new.", log.Fields{"group on the device": current, "new": new})
+	// get members to be added
+	membersToBeAdded := f.findDiff(current, new)
+	// get members to be removed
+	membersToBeRemoved := f.findDiff(new, current)
+
+	log.Infow("modify-group -> differences found", log.Fields{"membersToBeAdded": membersToBeAdded,
+		"membersToBeRemoved": membersToBeRemoved, "groupId": group.Desc.GroupId})
+
+	groupToOlt := openoltpb2.Group{
+		GroupId: group.Desc.GroupId,
+	}
+	var added, removed = true, true
+	if membersToBeAdded != nil && len(membersToBeAdded) > 0 {
+		groupToOlt.Command = openoltpb2.Group_ADD_MEMBERS
+		groupToOlt.Members = membersToBeAdded
+		//execute addMembers
+		added = f.callGroupAddRemove(&groupToOlt)
+	}
+	if membersToBeRemoved != nil && len(membersToBeRemoved) > 0 {
+		groupToOlt.Command = openoltpb2.Group_REMOVE_MEMBERS
+		groupToOlt.Members = membersToBeRemoved
+		//execute removeMembers
+		removed = f.callGroupAddRemove(&groupToOlt)
+	}
+
+	//save the modified group
+	if added && removed {
+		if err := f.resourceMgr.AddFlowGroupToKVStore(ctx, group, false); err != nil {
+			log.Errorw("Failed to save the group into kv store", log.Fields{"groupId": group.Desc.GroupId})
+		}
+		log.Debugw("modify-group was success. Storing the group", log.Fields{"group": group, "existingGroup": current})
+	} else {
+		log.Warnw("One of the group add/remove operations has failed. Cannot save group modifications",
+			log.Fields{"group": group})
+	}
+	return added && removed
+}
+
+//callGroupAddRemove performs add/remove buckets operation for the indicated group
+func (f *OpenOltFlowMgr) callGroupAddRemove(group *openoltpb2.Group) bool {
+	if err := f.performGroupOperation(group); err != nil {
+		st, _ := status.FromError(err)
+		//ignore already exists error code
+		if st.Code() != codes.AlreadyExists {
+			return false
+		}
+	}
+	return true
+}
+
+//findDiff compares group members and finds members which only exists in groups2
+func (f *OpenOltFlowMgr) findDiff(group1 *openoltpb2.Group, group2 *openoltpb2.Group) []*openoltpb2.GroupMember {
+	var members []*openoltpb2.GroupMember
+	for _, bucket := range group2.Members {
+		if !f.contains(group1.Members, bucket) {
+			// bucket does not exist and must be added
+			members = append(members, bucket)
+		}
+	}
+	return members
+}
+
+//contains returns true if the members list contains the given member; false otherwise
+func (f *OpenOltFlowMgr) contains(members []*openoltpb2.GroupMember, member *openoltpb2.GroupMember) bool {
+	for _, groupMember := range members {
+		if groupMember.InterfaceId == member.InterfaceId {
+			return true
+		}
+	}
+	return false
+}
+
+//performGroupOperation call performGroupOperation operation of openolt proto
+func (f *OpenOltFlowMgr) performGroupOperation(group *openoltpb2.Group) error {
+	log.Debugw("Sending group to device", log.Fields{"groupToOlt": group, "command": group.Command})
+	_, err := f.deviceHandler.Client.PerformGroupOperation(context.Background(), group)
+	if err != nil {
+		log.Errorw("group operation failed", log.Fields{"err": err, "groupToOlt": group})
+	}
+	return err
+}
+
+//buildGroup build openoltpb2.Group from given group id and bucket list
+func (f *OpenOltFlowMgr) buildGroup(groupID uint32, buckets []*ofp.OfpBucket) *openoltpb2.Group {
+	group := openoltpb2.Group{
+		GroupId: groupID}
+	// create members of the group
+	if buckets != nil {
+		for _, ofBucket := range buckets {
+			member := f.buildMember(ofBucket)
+			if member != nil && !f.contains(group.Members, member) {
+				group.Members = append(group.Members, member)
+			}
+		}
+	}
+	return &group
+}
+
+//buildMember builds openoltpb2.GroupMember from an OpenFlow bucket
+func (f *OpenOltFlowMgr) buildMember(ofBucket *ofp.OfpBucket) *openoltpb2.GroupMember {
+	var outPort uint32
+	outPortFound := false
+	for _, ofAction := range ofBucket.Actions {
+		if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
+			outPort = ofAction.GetOutput().Port
+			outPortFound = true
+		}
+	}
+
+	if !outPortFound {
+		log.Debugw("bucket skipped since no out port found in it",
+			log.Fields{"ofBucket": ofBucket})
+		return nil
+	}
+	interfaceID := IntfIDFromUniPortNum(outPort)
+	log.Debugw("got associated interface id of the port", log.Fields{"portNumber:": outPort, "interfaceId:": interfaceID})
+	if groupInfo, ok := f.interfaceToMcastQueueMap[interfaceID]; ok {
+		member := openoltpb2.GroupMember{
+			InterfaceId:   interfaceID,
+			InterfaceType: openoltpb2.GroupMember_PON,
+			GemPortId:     groupInfo.gemPortID,
+			Priority:      groupInfo.servicePriority,
+		}
+		//add member to the group
+		return &member
+	}
+	log.Warnf("bucket skipped since interface-2-gem mapping cannot be found",
+		log.Fields{"ofBucket": ofBucket})
+	return nil
+}
+
+//sendTPDownloadMsgToChild send payload
+func (f *OpenOltFlowMgr) sendTPDownloadMsgToChild(intfID uint32, onuID uint32, uniID uint32, uni string, TpID uint32) error {
+
+	onuDevice, err := f.getOnuChildDevice(intfID, onuID)
+	if err != nil {
+		log.Errorw("Error while fetching Child device from core", log.Fields{"onuId": onuID})
+		return err
+	}
+	log.Debugw("Got child device from OLT device handler", log.Fields{"device": *onuDevice})
+
+	tpPath := f.getTPpath(intfID, uni, TpID)
+	tpDownloadMsg := &ic.InterAdapterTechProfileDownloadMessage{UniId: uniID, Path: tpPath}
+	log.Infow("Sending Load-tech-profile-request-to-brcm-onu-adapter", log.Fields{"msg": *tpDownloadMsg})
+	sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(context.Background(),
+		tpDownloadMsg,
+		ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST,
+		f.deviceHandler.deviceType,
+		onuDevice.Type,
+		onuDevice.Id,
+		onuDevice.ProxyAddress.DeviceId, "")
+	if sendErr != nil {
+		log.Errorw("send techprofile-download request error", log.Fields{"fromAdapter": f.deviceHandler.deviceType,
+			"toAdapter": onuDevice.Type, "onuId": onuDevice.Id,
+			"proxyDeviceId": onuDevice.ProxyAddress.DeviceId})
+		return sendErr
+	}
+	log.Debugw("success Sending Load-tech-profile-request-to-brcm-onu-adapter", log.Fields{"msg": tpDownloadMsg})
+	return nil
+}
+
+//UpdateOnuInfo function adds onu info to cache and kvstore
+func (f *OpenOltFlowMgr) UpdateOnuInfo(ctx context.Context, intfID uint32, onuID uint32, serialNum string) {
+
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+	onu := rsrcMgr.OnuGemInfo{OnuID: onuID, SerialNumber: serialNum, IntfID: intfID}
+	f.onuGemInfo[intfID] = append(f.onuGemInfo[intfID], onu)
+	if err := f.resourceMgr.AddOnuGemInfo(ctx, intfID, onu); err != nil {
+		// TODO: VOL-2638
+		log.Errorw("failed to add onu info", log.Fields{"onu": onu})
+		return
+	}
+	log.Debugw("Updated onuinfo", log.Fields{"intfID": intfID, "onuID": onuID, "serialNum": serialNum})
+}
+
+//addGemPortToOnuInfoMap function adds GEMport to ONU map
+func (f *OpenOltFlowMgr) addGemPortToOnuInfoMap(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) {
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+	onugem := f.onuGemInfo[intfID]
+	// update the gem to the local cache as well as to kv strore
+	for idx, onu := range onugem {
+		if onu.OnuID == onuID {
+			// check if gem already exists , else update the cache and kvstore
+			for _, gem := range onu.GemPorts {
+				if gem == gemPort {
+					log.Debugw("Gem already in cache, no need to update cache and kv store",
+						log.Fields{"gem": gemPort})
+					return
+				}
+			}
+			onugem[idx].GemPorts = append(onugem[idx].GemPorts, gemPort)
+			f.onuGemInfo[intfID] = onugem
+		}
+	}
+	err := f.resourceMgr.AddGemToOnuGemInfo(ctx, intfID, onuID, gemPort)
+	if err != nil {
+		log.Errorw("Failed to add gem to onu", log.Fields{"intfId": intfID, "onuId": onuID, "gemPort": gemPort})
+		return
+	}
+}
+
+// This function Lookup maps  by serialNumber or (intfId, gemPort)
+
+//getOnuIDfromGemPortMap Returns OnuID,nil if found or set 0,error if no onuId is found for serialNumber or (intfId, gemPort)
+func (f *OpenOltFlowMgr) getOnuIDfromGemPortMap(serialNumber string, intfID uint32, gemPortID uint32) (uint32, error) {
+
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+
+	log.Debugw("Getting ONU ID from GEM port and PON port", log.Fields{"serialNumber": serialNumber, "intfId": intfID, "gemPortId": gemPortID})
+	// get onuid from the onugem info cache
+	onugem := f.onuGemInfo[intfID]
+	for _, onu := range onugem {
+		for _, gem := range onu.GemPorts {
+			if gem == gemPortID {
+				return onu.OnuID, nil
+			}
+		}
+	}
+	return uint32(0), NewErrNotFound("onu-id", log.Fields{
+		"serial-number": serialNumber,
+		"interface-id":  intfID,
+		"gem-port-id":   gemPortID},
+		nil).Log()
+}
+
+//GetLogicalPortFromPacketIn function computes logical port UNI/NNI port from packet-in indication and returns the same
+func (f *OpenOltFlowMgr) GetLogicalPortFromPacketIn(ctx context.Context, packetIn *openoltpb2.PacketIndication) (uint32, error) {
+	var logicalPortNum uint32
+	var onuID uint32
+	var err error
+
+	if packetIn.IntfType == "pon" {
+		// packet indication does not have serial number , so sending as nil
+		if onuID, err = f.getOnuIDfromGemPortMap("", packetIn.IntfId, packetIn.GemportId); err != nil {
+			log.Errorw("Unable to get ONU ID from GEM/PON port", log.Fields{"pon port": packetIn.IntfId, "gemport": packetIn.GemportId})
+			return logicalPortNum, err
+		}
+		if packetIn.PortNo != 0 {
+			logicalPortNum = packetIn.PortNo
+		} else {
+			uniID := uint32(0) //  FIXME - multi-uni support
+			logicalPortNum = MkUniPortNum(packetIn.IntfId, onuID, uniID)
+		}
+		// Store the gem port through which the packet_in came. Use the same gem port for packet_out
+		f.UpdateGemPortForPktIn(ctx, packetIn.IntfId, onuID, logicalPortNum, packetIn.GemportId)
+	} else if packetIn.IntfType == "nni" {
+		logicalPortNum = IntfIDToPortNo(packetIn.IntfId, voltha.Port_ETHERNET_NNI)
+	}
+	log.Debugw("Retrieved logicalport from  packet-in", log.Fields{
+		"logicalPortNum": logicalPortNum,
+		"IntfType":       packetIn.IntfType,
+		"packet":         hex.EncodeToString(packetIn.Pkt),
+	})
+	return logicalPortNum, nil
+}
+
+//GetPacketOutGemPortID returns gemPortId
+func (f *OpenOltFlowMgr) GetPacketOutGemPortID(ctx context.Context, intfID uint32, onuID uint32, portNum uint32) (uint32, error) {
+	var gemPortID uint32
+	var err error
+
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+	pktInkey := rsrcMgr.PacketInInfoKey{IntfID: intfID, OnuID: onuID, LogicalPort: portNum}
+
+	gemPortID, ok := f.packetInGemPort[pktInkey]
+	if ok {
+		log.Debugw("Found gemport for pktin key", log.Fields{"pktinkey": pktInkey, "gem": gemPortID})
+		return gemPortID, err
+	}
+	//If gem is not found in cache try to get it from kv store, if found in kv store, update the cache and return.
+	gemPortID, err = f.resourceMgr.GetGemPortFromOnuPktIn(ctx, intfID, onuID, portNum)
+	if err == nil {
+		if gemPortID != 0 {
+			f.packetInGemPort[pktInkey] = gemPortID
+			log.Debugw("Found gem port from kv store and updating cache with gemport",
+				log.Fields{"pktinkey": pktInkey, "gem": gemPortID})
+			return gemPortID, nil
+		}
+	}
+	log.Errorw("Failed to get gemport", log.Fields{"pktinkey": pktInkey, "gem": gemPortID})
+	return uint32(0), err
+}
+
+func installFlowOnAllGemports(ctx context.Context,
+	f1 func(ctx context.Context, intfId uint32, onuId uint32, uniId uint32,
+		portNo uint32, classifier map[string]interface{}, action map[string]interface{},
+		logicalFlow *ofp.OfpFlowStats, allocId uint32, gemPortId uint32) error,
+	f2 func(ctx context.Context, intfId uint32, onuId uint32, uniId uint32, portNo uint32,
+		classifier map[string]interface{}, action map[string]interface{},
+		logicalFlow *ofp.OfpFlowStats, allocId uint32, gemPortId uint32, vlanId uint32,
+	) error,
+	args map[string]uint32,
+	classifier map[string]interface{}, action map[string]interface{},
+	logicalFlow *ofp.OfpFlowStats,
+	gemPorts []uint32,
+	TpInst *tp.TechProfile,
+	FlowType string,
+	vlanID ...uint32) {
+	log.Debugw("Installing flow on all GEM ports", log.Fields{"FlowType": FlowType, "gemPorts": gemPorts, "vlan": vlanID})
+
+	for _, gemPortAttribute := range TpInst.UpstreamGemPortAttributeList {
+		var gemPortID uint32
+		// The bit mapping for a gemport is expressed in tech-profile as a binary string. For example, 0b00000001
+		// We need to trim prefix "0b", before further processing
+		// Once the "0b" prefix is trimmed, we iterate each character in the string to identify which index
+		// in the string is set to binary bit 1 (expressed as char '1' in the binary string).
+		for pos, pbitSet := range strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix) {
+			// If a particular character in the string is set to '1', identify the index of this character from
+			// the LSB position which marks the PCP bit consumed by the given gem port.
+			// This PCP bit now becomes a classifier in the flow.
+			if pbitSet == BinaryBit1 {
+				classifier[VlanPcp] = uint32(len(strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix))) - 1 - uint32(pos)
+				gemPortID = gemPortAttribute.GemportID
+				if FlowType == HsiaFlow || FlowType == DhcpFlow || FlowType == IgmpFlow {
+					f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID)
+				} else if FlowType == EapolFlow {
+					f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0])
+				} else {
+					log.Errorw("Unrecognized Flow Type", log.Fields{"FlowType": FlowType})
+					return
+				}
+			}
+		}
+	}
+}
+
+func (f *OpenOltFlowMgr) addDHCPTrapFlowOnNNI(ctx context.Context, logicalFlow *ofp.OfpFlowStats, classifier map[string]interface{}, portNo uint32) error {
+	log.Debug("Adding trap-dhcp-of-nni-flow")
+	action := make(map[string]interface{})
+	classifier[PacketTagType] = DoubleTag
+	action[TrapToHost] = true
+	/* We manage flowId resource pool on per PON port basis.
+	   Since this situation is tricky, as a hack, we pass the NNI port
+	   index (network_intf_id) as PON port Index for the flowId resource
+	   pool. Also, there is no ONU Id available for trapping DHCP packets
+	   on NNI port, use onu_id as -1 (invalid)
+	   ****************** CAVEAT *******************
+	   This logic works if the NNI Port Id falls within the same valid
+	   range of PON Port Ids. If this doesn't work for some OLT Vendor
+	   we need to have a re-look at this.
+	   *********************************************
+	*/
+	onuID := -1
+	uniID := -1
+	gemPortID := -1
+	allocID := -1
+	networkInterfaceID, err := getNniIntfID(classifier, action)
+	if err != nil {
+		return NewErrNotFound("nni-intreface-id", log.Fields{
+			"classifier": classifier,
+			"action":     action},
+			err).Log()
+	}
+
+	flowStoreCookie := getFlowStoreCookie(classifier, uint32(0))
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("Flow-exists-not-re-adding")
+		return nil
+	}
+	flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0)
+	if err != nil {
+		return NewErrNotFound("dhcp-trap-nni-flow-id", log.Fields{
+			"interface-id": networkInterfaceID,
+			"onu-id":       onuID,
+			"uni-id":       uniID,
+			"gem-port-id":  gemPortID,
+			"cookie":       flowStoreCookie},
+			err).Log()
+	}
+	classifierProto, err := makeOpenOltClassifierField(classifier)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
+	}
+	log.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(action)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": action}, err).Log()
+	}
+	log.Debugw("Created action proto", log.Fields{"action": *actionProto})
+	downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
+		OnuId:         int32(onuID), // OnuId not required
+		UniId:         int32(uniID), // UniId not used
+		FlowId:        flowID,
+		FlowType:      Downstream,
+		AllocId:       int32(allocID), // AllocId not used
+		NetworkIntfId: int32(networkInterfaceID),
+		GemportId:     int32(gemPortID), // GemportId not used
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(logicalFlow.Priority),
+		Cookie:        logicalFlow.Cookie,
+		PortNo:        portNo}
+	if err := f.addFlowToDevice(ctx, logicalFlow, &downstreamflow); err != nil {
+		return NewErrFlowOp("add", flowID, log.Fields{"flow": downstreamflow}, err).Log()
+	}
+	log.Debug("DHCP trap on NNI flow added to device successfully")
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &downstreamflow, flowStoreCookie, "", flowID, logicalFlow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, int32(networkInterfaceID),
+		int32(onuID),
+		int32(uniID),
+		flowID, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", flowID, log.Fields{"flow": downstreamflow}, err).Log()
+	}
+	return nil
+}
+
+//getPacketTypeFromClassifiers finds and returns packet type of a flow by checking flow classifiers
+func getPacketTypeFromClassifiers(classifierInfo map[string]interface{}) string {
+	var packetType string
+	ovid, ivid := false, false
+	if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
+		vid := vlanID & VlanvIDMask
+		if vid != ReservedVlan {
+			ovid = true
+		}
+	}
+	if metadata, ok := classifierInfo[Metadata].(uint64); ok {
+		vid := uint32(metadata)
+		if vid != ReservedVlan {
+			ivid = true
+		}
+	}
+	if ovid && ivid {
+		packetType = DoubleTag
+	} else if !ovid && !ivid {
+		packetType = Untagged
+	} else {
+		packetType = SingleTag
+	}
+	return packetType
+}
+
+//addIgmpTrapFlowOnNNI adds a trap-to-host flow on NNI
+func (f *OpenOltFlowMgr) addIgmpTrapFlowOnNNI(ctx context.Context, logicalFlow *ofp.OfpFlowStats, classifier map[string]interface{}, portNo uint32) error {
+	log.Debugw("Adding igmp-trap-of-nni-flow", log.Fields{"classifierInfo": classifier})
+	action := make(map[string]interface{})
+	classifier[PacketTagType] = getPacketTypeFromClassifiers(classifier)
+	action[TrapToHost] = true
+	/* We manage flowId resource pool on per PON port basis.
+	   Since this situation is tricky, as a hack, we pass the NNI port
+	   index (network_intf_id) as PON port Index for the flowId resource
+	   pool. Also, there is no ONU Id available for trapping packets
+	   on NNI port, use onu_id as -1 (invalid)
+	   ****************** CAVEAT *******************
+	   This logic works if the NNI Port Id falls within the same valid
+	   range of PON Port Ids. If this doesn't work for some OLT Vendor
+	   we need to have a re-look at this.
+	   *********************************************
+	*/
+	onuID := -1
+	uniID := -1
+	gemPortID := -1
+	allocID := -1
+	networkInterfaceID, err := getNniIntfID(classifier, action)
+	if err != nil {
+		return NewErrNotFound("nni-interface-id", log.Fields{
+			"classifier": classifier,
+			"action":     action},
+			err).Log()
+	}
+	flowStoreCookie := getFlowStoreCookie(classifier, uint32(0))
+	if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), flowStoreCookie); present {
+		log.Debug("igmp-flow-exists-not-re-adding")
+		return nil
+	}
+	flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0, 0)
+	if err != nil {
+		return NewErrNotFound("igmp-flow-id", log.Fields{
+			"interface-id": networkInterfaceID,
+			"onu-id":       onuID,
+			"uni-id":       uniID,
+			"gem-port-id":  gemPortID,
+			"cookie":       flowStoreCookie},
+			err).Log()
+	}
+	classifierProto, err := makeOpenOltClassifierField(classifier)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
+	}
+	log.Debugw("Created classifier proto for the IGMP flow", log.Fields{"classifier": *classifierProto})
+	actionProto, err := makeOpenOltActionField(action)
+	if err != nil {
+		return NewErrInvalidValue(log.Fields{"action": action}, err).Log()
+	}
+	log.Debugw("Created action proto for the IGMP flow", log.Fields{"action": *actionProto})
+	downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
+		OnuId:         int32(onuID), // OnuId not required
+		UniId:         int32(uniID), // UniId not used
+		FlowId:        flowID,
+		FlowType:      Downstream,
+		AllocId:       int32(allocID), // AllocId not used
+		NetworkIntfId: int32(networkInterfaceID),
+		GemportId:     int32(gemPortID), // GemportId not used
+		Classifier:    classifierProto,
+		Action:        actionProto,
+		Priority:      int32(logicalFlow.Priority),
+		Cookie:        logicalFlow.Cookie,
+		PortNo:        portNo}
+	if err := f.addFlowToDevice(ctx, logicalFlow, &downstreamflow); err != nil {
+		return NewErrFlowOp("add", flowID, log.Fields{"flow": downstreamflow}, err).Log()
+	}
+	log.Debug("IGMP Trap on NNI flow added to device successfully")
+	flowsToKVStore := f.getUpdatedFlowInfo(ctx, &downstreamflow, flowStoreCookie, "", flowID, logicalFlow.Id)
+	if err := f.updateFlowInfoToKVStore(ctx, int32(networkInterfaceID),
+		int32(onuID),
+		int32(uniID),
+		flowID, flowsToKVStore); err != nil {
+		return NewErrPersistence("update", "flow", flowID, log.Fields{"flow": downstreamflow}, err).Log()
+	}
+	return nil
+}
+
+func verifyMeterIDAndGetDirection(MeterID uint32, Dir tp_pb.Direction) (string, error) {
+	if MeterID == 0 { // This should never happen
+		return "", NewErrInvalidValue(log.Fields{"meter-id": MeterID}, nil).Log()
+	}
+	if Dir == tp_pb.Direction_UPSTREAM {
+		return "upstream", nil
+	} else if Dir == tp_pb.Direction_DOWNSTREAM {
+		return "downstream", nil
+	}
+	return "", nil
+}
+
+func (f *OpenOltFlowMgr) checkAndAddFlow(ctx context.Context, args map[string]uint32, classifierInfo map[string]interface{},
+	actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpInst *tp.TechProfile, gemPorts []uint32,
+	TpID uint32, uni string) {
+	var gemPort uint32
+	intfID := args[IntfID]
+	onuID := args[OnuID]
+	uniID := args[UniID]
+	portNo := args[PortNo]
+	allocID := TpInst.UsScheduler.AllocID
+	if ipProto, ok := classifierInfo[IPProto]; ok {
+		if ipProto.(uint32) == IPProtoDhcp {
+			log.Info("Adding DHCP flow")
+			if pcp, ok := classifierInfo[VlanPcp]; ok {
+				gemPort = f.techprofile[intfID].GetGemportIDForPbit(TpInst,
+					tp_pb.Direction_UPSTREAM,
+					pcp.(uint32))
+				//Adding DHCP upstream flow
+				f.addDHCPTrapFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
+			} else {
+				//Adding DHCP upstream flow to all gemports
+				installFlowOnAllGemports(ctx, f.addDHCPTrapFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, DhcpFlow)
+			}
+
+		} else if ipProto == IgmpProto {
+			log.Infow("Adding Us IGMP flow", log.Fields{"intfID": intfID, "onuID": onuID, "uniID": uniID, "classifierInfo:": classifierInfo})
+			if pcp, ok := classifierInfo[VlanPcp]; ok {
+				gemPort = f.techprofile[intfID].GetGemportIDForPbit(TpInst,
+					tp_pb.Direction_UPSTREAM,
+					pcp.(uint32))
+				f.addIGMPTrapFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
+			} else {
+				//Adding IGMP upstream flow to all gem ports
+				installFlowOnAllGemports(ctx, f.addIGMPTrapFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, IgmpFlow)
+			}
+		} else {
+			log.Errorw("Invalid-Classifier-to-handle", log.Fields{"classifier": classifierInfo, "action": actionInfo})
+			return
+		}
+	} else if ethType, ok := classifierInfo[EthType]; ok {
+		if ethType.(uint32) == EapEthType {
+			log.Info("Adding EAPOL flow")
+			var vlanID uint32
+			if val, ok := classifierInfo[VlanVid]; ok {
+				vlanID = (val.(uint32)) & VlanvIDMask
+			} else {
+				vlanID = DefaultMgmtVlan
+			}
+			if pcp, ok := classifierInfo[VlanPcp]; ok {
+				gemPort = f.techprofile[intfID].GetGemportIDForPbit(TpInst,
+					tp_pb.Direction_UPSTREAM,
+					pcp.(uint32))
+
+				f.addEAPOLFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort, vlanID)
+			} else {
+				installFlowOnAllGemports(ctx, nil, f.addEAPOLFlow, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, EapolFlow, vlanID)
+			}
+		}
+	} else if _, ok := actionInfo[PushVlan]; ok {
+		log.Info("Adding upstream data rule")
+		if pcp, ok := classifierInfo[VlanPcp]; ok {
+			gemPort = f.techprofile[intfID].GetGemportIDForPbit(TpInst,
+				tp_pb.Direction_UPSTREAM,
+				pcp.(uint32))
+			//Adding HSIA upstream flow
+			f.addUpstreamDataFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
+		} else {
+			//Adding HSIA upstream flow to all gemports
+			installFlowOnAllGemports(ctx, f.addUpstreamDataFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, HsiaFlow)
+		}
+	} else if _, ok := actionInfo[PopVlan]; ok {
+		log.Info("Adding Downstream data rule")
+		if pcp, ok := classifierInfo[VlanPcp]; ok {
+			gemPort = f.techprofile[intfID].GetGemportIDForPbit(TpInst,
+				tp_pb.Direction_DOWNSTREAM,
+				pcp.(uint32))
+			//Adding HSIA downstream flow
+			f.addDownstreamDataFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
+		} else {
+			//Adding HSIA downstream flow to all gemports
+			installFlowOnAllGemports(ctx, f.addDownstreamDataFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, HsiaFlow)
+		}
+	} else {
+		log.Errorw("Invalid-flow-type-to-handle", log.Fields{"classifier": classifierInfo, "action": actionInfo, "flow": flow})
+		return
+	}
+	// Send Techprofile download event to child device in go routine as it takes time
+	go f.sendTPDownloadMsgToChild(intfID, onuID, uniID, uni, TpID)
+}
+
+func (f *OpenOltFlowMgr) isGemPortUsedByAnotherFlow(gemPK gemPortKey) bool {
+	flowIDList := f.flowsUsedByGemPort[gemPK]
+	if len(flowIDList) > 1 {
+		return true
+	}
+	return false
+}
+
+func (f *OpenOltFlowMgr) isTechProfileUsedByAnotherGem(ctx context.Context, ponIntf uint32, onuID uint32, uniID uint32, tpID uint32, tpInst *tp.TechProfile, gemPortID uint32) (bool, uint32) {
+	currentGemPorts := f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, ponIntf, onuID, uniID)
+	tpGemPorts := tpInst.UpstreamGemPortAttributeList
+	for _, currentGemPort := range currentGemPorts {
+		for _, tpGemPort := range tpGemPorts {
+			if (currentGemPort == tpGemPort.GemportID) && (currentGemPort != gemPortID) {
+				return true, currentGemPort
+			}
+		}
+	}
+	if tpInst.InstanceCtrl.Onu == "single-instance" {
+		// The TP information for the given TP ID, PON ID, ONU ID, UNI ID should be removed.
+		f.resourceMgr.RemoveTechProfileIDForOnu(ctx, ponIntf, uint32(onuID), uint32(uniID), tpID)
+		f.DeleteTechProfileInstance(ctx, ponIntf, uint32(onuID), uint32(uniID), "", tpID)
+
+		// Although we cleaned up TP Instance for the given (PON ID, ONU ID, UNI ID), the TP might
+		// still be used on other uni ports.
+		// So, we need to check and make sure that no other gem port is referring to the given TP ID
+		// on any other uni port.
+		tpInstances := f.techprofile[ponIntf].FindAllTpInstances(ctx, tpID, ponIntf, onuID)
+		log.Debugw("got single instance tp instances", log.Fields{"tpInstances": tpInstances})
+		for i := 0; i < len(tpInstances); i++ {
+			tpI := tpInstances[i]
+			tpGemPorts := tpI.UpstreamGemPortAttributeList
+			for _, tpGemPort := range tpGemPorts {
+				if tpGemPort.GemportID != gemPortID {
+					log.Debugw("single instance tp is in use by gem", log.Fields{"gemPort": tpGemPort.GemportID})
+					return true, tpGemPort.GemportID
+				}
+			}
+		}
+	}
+	log.Debug("tech profile is not in use by any gem")
+	return false, 0
+}
+
+func formulateClassifierInfoFromFlow(classifierInfo map[string]interface{}, flow *ofp.OfpFlowStats) {
+	for _, field := range flows.GetOfbFields(flow) {
+		if field.Type == flows.ETH_TYPE {
+			classifierInfo[EthType] = field.GetEthType()
+			log.Debug("field-type-eth-type", log.Fields{"classifierInfo[ETH_TYPE]": classifierInfo[EthType].(uint32)})
+		} else if field.Type == flows.ETH_DST {
+			classifierInfo[EthDst] = field.GetEthDst()
+			log.Debug("field-type-eth-type", log.Fields{"classifierInfo[ETH_DST]": classifierInfo[EthDst].([]uint8)})
+		} else if field.Type == flows.IP_PROTO {
+			classifierInfo[IPProto] = field.GetIpProto()
+			log.Debug("field-type-ip-proto", log.Fields{"classifierInfo[IP_PROTO]": classifierInfo[IPProto].(uint32)})
+		} else if field.Type == flows.IN_PORT {
+			classifierInfo[InPort] = field.GetPort()
+			log.Debug("field-type-in-port", log.Fields{"classifierInfo[IN_PORT]": classifierInfo[InPort].(uint32)})
+		} else if field.Type == flows.VLAN_VID {
+			classifierInfo[VlanVid] = field.GetVlanVid() & 0xfff
+			log.Debug("field-type-vlan-vid", log.Fields{"classifierInfo[VLAN_VID]": classifierInfo[VlanVid].(uint32)})
+		} else if field.Type == flows.VLAN_PCP {
+			classifierInfo[VlanPcp] = field.GetVlanPcp()
+			log.Debug("field-type-vlan-pcp", log.Fields{"classifierInfo[VLAN_PCP]": classifierInfo[VlanPcp].(uint32)})
+		} else if field.Type == flows.UDP_DST {
+			classifierInfo[UDPDst] = field.GetUdpDst()
+			log.Debug("field-type-udp-dst", log.Fields{"classifierInfo[UDP_DST]": classifierInfo[UDPDst].(uint32)})
+		} else if field.Type == flows.UDP_SRC {
+			classifierInfo[UDPSrc] = field.GetUdpSrc()
+			log.Debug("field-type-udp-src", log.Fields{"classifierInfo[UDP_SRC]": classifierInfo[UDPSrc].(uint32)})
+		} else if field.Type == flows.IPV4_DST {
+			classifierInfo[Ipv4Dst] = field.GetIpv4Dst()
+			log.Debug("field-type-ipv4-dst", log.Fields{"classifierInfo[IPV4_DST]": classifierInfo[Ipv4Dst].(uint32)})
+		} else if field.Type == flows.IPV4_SRC {
+			classifierInfo[Ipv4Src] = field.GetIpv4Src()
+			log.Debug("field-type-ipv4-src", log.Fields{"classifierInfo[IPV4_SRC]": classifierInfo[Ipv4Src].(uint32)})
+		} else if field.Type == flows.METADATA {
+			classifierInfo[Metadata] = field.GetTableMetadata()
+			log.Debug("field-type-metadata", log.Fields{"classifierInfo[Metadata]": classifierInfo[Metadata].(uint64)})
+		} else if field.Type == flows.TUNNEL_ID {
+			classifierInfo[TunnelID] = field.GetTunnelId()
+			log.Debug("field-type-tunnelId", log.Fields{"classifierInfo[TUNNEL_ID]": classifierInfo[TunnelID].(uint64)})
+		} else {
+			log.Errorw("Un supported field type", log.Fields{"type": field.Type})
+			return
+		}
+	}
+}
+
+func formulateActionInfoFromFlow(actionInfo, classifierInfo map[string]interface{}, flow *ofp.OfpFlowStats) error {
+	for _, action := range flows.GetActions(flow) {
+		if action.Type == flows.OUTPUT {
+			if out := action.GetOutput(); out != nil {
+				actionInfo[Output] = out.GetPort()
+				log.Debugw("action-type-output", log.Fields{"out_port": actionInfo[Output].(uint32)})
+			} else {
+				return NewErrInvalidValue(log.Fields{"output-port": nil}, nil).Log()
+			}
+		} else if action.Type == flows.POP_VLAN {
+			actionInfo[PopVlan] = true
+			log.Debugw("action-type-pop-vlan", log.Fields{"in_port": classifierInfo[InPort].(uint32)})
+		} else if action.Type == flows.PUSH_VLAN {
+			if out := action.GetPush(); out != nil {
+				if tpid := out.GetEthertype(); tpid != 0x8100 {
+					log.Errorw("Invalid ethertype in push action", log.Fields{"ethertype": actionInfo[PushVlan].(int32)})
+				} else {
+					actionInfo[PushVlan] = true
+					actionInfo[TPID] = tpid
+					log.Debugw("action-type-push-vlan",
+						log.Fields{"push_tpid": actionInfo[TPID].(uint32), "in_port": classifierInfo[InPort].(uint32)})
+				}
+			}
+		} else if action.Type == flows.SET_FIELD {
+			if out := action.GetSetField(); out != nil {
+				if field := out.GetField(); field != nil {
+					if ofClass := field.GetOxmClass(); ofClass != ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
+						return NewErrInvalidValue(log.Fields{"openflow-class": ofClass}, nil).Log()
+					}
+					/*log.Debugw("action-type-set-field",log.Fields{"field": field, "in_port": classifierInfo[IN_PORT].(uint32)})*/
+					formulateSetFieldActionInfoFromFlow(field, actionInfo)
+				}
+			}
+		} else if action.Type == flows.GROUP {
+			formulateGroupActionInfoFromFlow(action, actionInfo)
+		} else {
+			return NewErrInvalidValue(log.Fields{"action-type": action.Type}, nil).Log()
+		}
+	}
+	return nil
+}
+
+func formulateSetFieldActionInfoFromFlow(field *ofp.OfpOxmField, actionInfo map[string]interface{}) {
+	if ofbField := field.GetOfbField(); ofbField != nil {
+		if fieldtype := ofbField.GetType(); fieldtype == ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
+			if vlan := ofbField.GetVlanVid(); vlan != 0 {
+				actionInfo[VlanVid] = vlan & 0xfff
+				log.Debugw("action-set-vlan-vid", log.Fields{"actionInfo[VLAN_VID]": actionInfo[VlanVid].(uint32)})
+			} else {
+				log.Error("No Invalid vlan id in set vlan-vid action")
+			}
+		} else {
+			log.Errorw("unsupported-action-set-field-type", log.Fields{"type": fieldtype})
+		}
+	}
+}
+
+func formulateGroupActionInfoFromFlow(action *ofp.OfpAction, actionInfo map[string]interface{}) {
+	if action.GetGroup() == nil {
+		log.Warn("No group entry found in the group action")
+	} else {
+		actionInfo[GroupID] = action.GetGroup().GroupId
+		log.Debugw("action-group-id", log.Fields{"actionInfo[GroupID]": actionInfo[GroupID].(uint32)})
+	}
+}
+
+func formulateControllerBoundTrapFlowInfo(actionInfo, classifierInfo map[string]interface{}, flow *ofp.OfpFlowStats) error {
+	if isControllerFlow := IsControllerBoundFlow(actionInfo[Output].(uint32)); isControllerFlow {
+		log.Debug("Controller bound trap flows, getting inport from tunnelid")
+		/* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows  */
+		if portType := IntfIDToPortTypeName(classifierInfo[InPort].(uint32)); portType == voltha.Port_PON_OLT {
+			if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
+				classifierInfo[InPort] = uniPort
+				log.Debugw("upstream pon-to-controller-flow,inport-in-tunnelid", log.Fields{"newInPort": classifierInfo[InPort].(uint32), "outPort": actionInfo[Output].(uint32)})
+			} else {
+				return NewErrNotFound("child-in-port", log.Fields{
+					"reason": "upstream pon-to-controller-flow, NO-inport-in-tunnelid",
+					"flow":   flow}, nil).Log()
+			}
+		}
+	} else {
+		log.Debug("Non-Controller flows, getting uniport from tunnelid")
+		// Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
+		if portType := IntfIDToPortTypeName(actionInfo[Output].(uint32)); portType == voltha.Port_PON_OLT {
+			if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
+				actionInfo[Output] = uniPort
+				log.Debugw("downstream-nni-to-pon-port-flow, outport-in-tunnelid", log.Fields{"newOutPort": actionInfo[Output].(uint32), "outPort": actionInfo[Output].(uint32)})
+			} else {
+				return NewErrNotFound("out-port", log.Fields{
+					"reason": "downstream-nni-to-pon-port-flow, no-outport-in-tunnelid",
+					"flow":   flow}, nil).Log()
+			}
+			// Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
+		} else if portType := IntfIDToPortTypeName(classifierInfo[InPort].(uint32)); portType == voltha.Port_PON_OLT {
+			if uniPort := flows.GetChildPortFromTunnelId(flow); uniPort != 0 {
+				classifierInfo[InPort] = uniPort
+				log.Debugw("upstream-pon-to-nni-port-flow, inport-in-tunnelid", log.Fields{"newInPort": actionInfo[Output].(uint32),
+					"outport": actionInfo[Output].(uint32)})
+			} else {
+				return NewErrNotFound("nni-port", log.Fields{
+					"reason":   "upstream-pon-to-nni-port-flow, no-inport-in-tunnelid",
+					"in-port":  classifierInfo[InPort].(uint32),
+					"out-port": actionInfo[Output].(uint32),
+					"flow":     flow}, nil).Log()
+			}
+		}
+	}
+	return nil
+}
+
+func getTpIDFromFlow(flow *ofp.OfpFlowStats) (uint32, error) {
+	/*     Metadata 8 bytes:
+		   Most Significant 2 Bytes = Inner VLAN
+		   Next 2 Bytes = Tech Profile ID(TPID)
+		   Least Significant 4 Bytes = Port ID
+	       Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
+	       subscriber related flows.
+	*/
+	metadata := flows.GetMetadataFromWriteMetadataAction(flow)
+	if metadata == 0 {
+		return 0, NewErrNotFound("metadata", log.Fields{"flow": flow}, nil).Log()
+	}
+	TpID := flows.GetTechProfileIDFromWriteMetaData(metadata)
+	return uint32(TpID), nil
+}
+
+func appendUnique(slice []uint32, item uint32) []uint32 {
+	for _, sliceElement := range slice {
+		if sliceElement == item {
+			return slice
+		}
+	}
+	return append(slice, item)
+}
+
+// getNniIntfID gets nni intf id from the flow classifier/action
+func getNniIntfID(classifier map[string]interface{}, action map[string]interface{}) (uint32, error) {
+
+	portType := IntfIDToPortTypeName(classifier[InPort].(uint32))
+	if portType == voltha.Port_PON_OLT {
+		intfID, err := IntfIDFromNniPortNum(action[Output].(uint32))
+		if err != nil {
+			log.Debugw("invalid-action-port-number",
+				log.Fields{
+					"port-number": action[Output].(uint32),
+					"error":       err})
+			return uint32(0), err
+		}
+		log.Debugw("output Nni IntfID is", log.Fields{"intfid": intfID})
+		return intfID, nil
+	} else if portType == voltha.Port_ETHERNET_NNI {
+		intfID, err := IntfIDFromNniPortNum(classifier[InPort].(uint32))
+		if err != nil {
+			log.Debugw("invalid-classifier-port-number",
+				log.Fields{
+					"port-number": action[Output].(uint32),
+					"error":       err})
+			return uint32(0), err
+		}
+		log.Debugw("input Nni IntfID is", log.Fields{"intfid": intfID})
+		return intfID, nil
+	}
+	return uint32(0), nil
+}
+
+// UpdateGemPortForPktIn updates gemport for packet-in in to the cache and to the kv store as well.
+func (f *OpenOltFlowMgr) UpdateGemPortForPktIn(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32, gemPort uint32) {
+	pktInkey := rsrcMgr.PacketInInfoKey{IntfID: intfID, OnuID: onuID, LogicalPort: logicalPort}
+
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+	lookupGemPort, ok := f.packetInGemPort[pktInkey]
+	if ok {
+		if lookupGemPort == gemPort {
+			log.Debugw("pktin key/value found in cache , no need to update kv as we are assuming both will be in sync",
+				log.Fields{"pktinkey": pktInkey, "gem": gemPort})
+			return
+		}
+	}
+	f.packetInGemPort[pktInkey] = gemPort
+
+	f.resourceMgr.UpdateGemPortForPktIn(ctx, pktInkey, gemPort)
+	log.Debugw("pktin key not found in local cache or value is different. updating cache and kv store", log.Fields{"pktinkey": pktInkey, "gem": gemPort})
+	return
+}
+
+// AddUniPortToOnuInfo adds uni port to the onugem info both in cache and kvstore.
+func (f *OpenOltFlowMgr) AddUniPortToOnuInfo(ctx context.Context, intfID uint32, onuID uint32, portNum uint32) {
+
+	f.lockCache.Lock()
+	defer f.lockCache.Unlock()
+	onugem := f.onuGemInfo[intfID]
+	for idx, onu := range onugem {
+		if onu.OnuID == onuID {
+			for _, uni := range onu.UniPorts {
+				if uni == portNum {
+					log.Debugw("uni already in cache, no need to update cache and kv store",
+						log.Fields{"uni": portNum})
+					return
+				}
+			}
+			onugem[idx].UniPorts = append(onugem[idx].UniPorts, portNum)
+			f.onuGemInfo[intfID] = onugem
+		}
+	}
+	f.resourceMgr.AddUniPortToOnuInfo(ctx, intfID, onuID, portNum)
+}
+
+func (f *OpenOltFlowMgr) loadFlowIDlistForGem(ctx context.Context, intf uint32) {
+	flowIDsList, err := f.resourceMgr.GetFlowIDsGemMapForInterface(ctx, intf)
+	if err != nil {
+		log.Error("Failed to get flowid list per gem", log.Fields{"intf": intf})
+		return
+	}
+	for gem, FlowIDs := range flowIDsList {
+		gemPK := gemPortKey{intf, uint32(gem)}
+		f.flowsUsedByGemPort[gemPK] = FlowIDs
+	}
+	return
+}
+
+//loadInterfaceToMulticastQueueMap reads multicast queues per interface from the KV store
+//and put them into interfaceToMcastQueueMap.
+func (f *OpenOltFlowMgr) loadInterfaceToMulticastQueueMap(ctx context.Context) {
+	storedMulticastQueueMap, err := f.resourceMgr.GetMcastQueuePerInterfaceMap(ctx)
+	if err != nil {
+		log.Error("Failed to get pon interface to multicast queue map")
+		return
+	}
+	for intf, queueInfo := range storedMulticastQueueMap {
+		q := queueInfoBrief{
+			gemPortID:       queueInfo[0],
+			servicePriority: queueInfo[1],
+		}
+		f.interfaceToMcastQueueMap[intf] = &q
+	}
+}
+
+//GetFlowGroupFromKVStore fetches and returns flow group from the KV store. Returns (nil, false, error) if any problem occurs during
+//fetching the data. Returns (group, true, nil) if the group is fetched and returned successfully.
+//Returns (nil, false, nil) if the group does not exists in the KV store.
+func (f *OpenOltFlowMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (*ofp.OfpGroupEntry, bool, error) {
+	exists, groupInfo, err := f.resourceMgr.GetFlowGroupFromKVStore(ctx, groupID, cached)
+	if err != nil {
+		return nil, false, NewErrNotFound("flow-group", log.Fields{"group-id": groupID}, err).Log()
+	}
+	if exists {
+		return newGroup(groupInfo.GroupID, groupInfo.OutPorts), exists, nil
+	}
+	return nil, exists, nil
+}
+
+func newGroup(groupID uint32, outPorts []uint32) *ofp.OfpGroupEntry {
+	groupDesc := ofp.OfpGroupDesc{
+		Type:    ofp.OfpGroupType_OFPGT_ALL,
+		GroupId: groupID,
+	}
+	groupEntry := ofp.OfpGroupEntry{
+		Desc: &groupDesc,
+	}
+	for i := 0; i < len(outPorts); i++ {
+		var acts []*ofp.OfpAction
+		acts = append(acts, flows.Output(outPorts[i]))
+		bucket := ofp.OfpBucket{
+			Actions: acts,
+		}
+		groupDesc.Buckets = append(groupDesc.Buckets, &bucket)
+	}
+	return &groupEntry
+}
diff --git a/internal/pkg/core/openolt_flowmgr_test.go b/internal/pkg/core/openolt_flowmgr_test.go
new file mode 100644
index 0000000..2890b19
--- /dev/null
+++ b/internal/pkg/core/openolt_flowmgr_test.go
@@ -0,0 +1,996 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"fmt"
+	"testing"
+	"time"
+
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/db"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
+	"github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
+	rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
+	"github.com/opencord/voltha-openolt-adapter/pkg/mocks"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/openolt"
+	openoltpb2 "github.com/opencord/voltha-protos/v3/go/openolt"
+	tp_pb "github.com/opencord/voltha-protos/v3/go/tech_profile"
+)
+
+var flowMgr *OpenOltFlowMgr
+
+func init() {
+	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
+	flowMgr = newMockFlowmgr()
+}
+func newMockResourceMgr() *resourcemanager.OpenOltResourceMgr {
+	ranges := []*openolt.DeviceInfo_DeviceResourceRanges{
+		{IntfIds: []uint32{0, 1, 2}}}
+
+	deviceinfo := &openolt.DeviceInfo{Vendor: "openolt", Model: "openolt", HardwareVersion: "1.0", FirmwareVersion: "1.0",
+		DeviceId: "olt", DeviceSerialNumber: "openolt", PonPorts: 3, Technology: "Default",
+		OnuIdStart: 1, OnuIdEnd: 1, AllocIdStart: 1, AllocIdEnd: 1,
+		GemportIdStart: 1, GemportIdEnd: 1, FlowIdStart: 1, FlowIdEnd: 1,
+		Ranges: ranges,
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	rsrMgr := resourcemanager.NewResourceMgr(ctx, "olt", "127.0.0.1:2379", "etcd", "olt", deviceinfo)
+	for key := range rsrMgr.ResourceMgrs {
+		rsrMgr.ResourceMgrs[key].KVStore = &db.Backend{}
+		rsrMgr.ResourceMgrs[key].KVStore.Client = &mocks.MockKVClient{}
+		rsrMgr.ResourceMgrs[key].TechProfileMgr = mocks.MockTechProfile{TpID: key}
+	}
+	return rsrMgr
+}
+
+func newMockFlowmgr() *OpenOltFlowMgr {
+	rMgr := newMockResourceMgr()
+	dh := newMockDeviceHandler()
+
+	rMgr.KVStore = &db.Backend{}
+	rMgr.KVStore.Client = &mocks.MockKVClient{}
+
+	dh.resourceMgr = rMgr
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	flwMgr := NewFlowManager(ctx, dh, rMgr)
+
+	onuGemInfo1 := make([]rsrcMgr.OnuGemInfo, 2)
+	onuGemInfo2 := make([]rsrcMgr.OnuGemInfo, 2)
+	onuGemInfo1[0] = rsrcMgr.OnuGemInfo{OnuID: 1, SerialNumber: "1", IntfID: 1, GemPorts: []uint32{1}}
+	onuGemInfo2[1] = rsrcMgr.OnuGemInfo{OnuID: 2, SerialNumber: "2", IntfID: 2, GemPorts: []uint32{2}}
+	flwMgr.onuGemInfo[1] = onuGemInfo1
+	flwMgr.onuGemInfo[2] = onuGemInfo2
+
+	packetInGemPort := make(map[rsrcMgr.PacketInInfoKey]uint32)
+	packetInGemPort[rsrcMgr.PacketInInfoKey{IntfID: 1, OnuID: 1, LogicalPort: 1}] = 1
+	packetInGemPort[rsrcMgr.PacketInInfoKey{IntfID: 2, OnuID: 2, LogicalPort: 2}] = 2
+
+	flwMgr.packetInGemPort = packetInGemPort
+	tps := make(map[uint32]tp.TechProfileIf)
+	for key := range rMgr.ResourceMgrs {
+		tps[key] = mocks.MockTechProfile{TpID: key}
+	}
+	flwMgr.techprofile = tps
+
+	interface2mcastQeueuMap := make(map[uint32]*queueInfoBrief)
+	interface2mcastQeueuMap[0] = &queueInfoBrief{
+		gemPortID:       4000,
+		servicePriority: 3,
+	}
+	flwMgr.interfaceToMcastQueueMap = interface2mcastQeueuMap
+	return flwMgr
+}
+
+func TestOpenOltFlowMgr_CreateSchedulerQueues(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+
+	tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
+		ProfileType: "pt1", NumGemPorts: 1, Version: 1,
+		InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
+	}
+	tprofile.UsScheduler.Direction = "UPSTREAM"
+	tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
+	tprofile.UsScheduler.QSchedPolicy = "WRR"
+
+	tprofile2 := tprofile
+	tprofile2.DsScheduler.Direction = "DOWNSTREAM"
+	tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
+	tprofile2.DsScheduler.QSchedPolicy = "WRR"
+	bands := make([]*ofp.OfpMeterBandHeader, 2)
+	bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
+	bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
+	ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
+	flowmetadata := &voltha.FlowMetadata{
+		Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
+	}
+	type args struct {
+		Dir          tp_pb.Direction
+		IntfID       uint32
+		OnuID        uint32
+		UniID        uint32
+		UniPort      uint32
+		TpInst       *tp.TechProfile
+		MeterID      uint32
+		flowMetadata *voltha.FlowMetadata
+	}
+	tests := []struct {
+		name       string
+		schedQueue schedQueue
+		wantErr    bool
+	}{
+		// TODO: Add test cases.
+		{"CreateSchedulerQueues-1", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, flowmetadata}, false},
+		{"CreateSchedulerQueues-2", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
+		{"CreateSchedulerQueues-3", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, flowmetadata}, true},
+		{"CreateSchedulerQueues-4", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, flowmetadata}, true},
+		{"CreateSchedulerQueues-5", schedQueue{tp_pb.Direction_UPSTREAM, 2, 2, 2, 64, 2, tprofile, 2, flowmetadata}, true},
+		{"CreateSchedulerQueues-6", schedQueue{tp_pb.Direction_DOWNSTREAM, 2, 2, 2, 65, 2, tprofile2, 2, flowmetadata}, true},
+		{"CreateSchedulerQueues-13", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, flowmetadata}, false},
+		//Negative testcases
+		{"CreateSchedulerQueues-7", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 1, &voltha.FlowMetadata{}}, true},
+		{"CreateSchedulerQueues-8", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, &voltha.FlowMetadata{}}, true},
+		{"CreateSchedulerQueues-9", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 1, &voltha.FlowMetadata{}}, true},
+		{"CreateSchedulerQueues-10", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 2, &voltha.FlowMetadata{}}, true},
+		{"CreateSchedulerQueues-11", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, &voltha.FlowMetadata{}}, true},
+		{"CreateSchedulerQueues-12", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 2, nil}, true},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := flowMgr.CreateSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
+				t.Errorf("OpenOltFlowMgr.CreateSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_RemoveSchedulerQueues(t *testing.T) {
+
+	// flowMgr := newMockFlowmgr()
+	tprofile := &tp.TechProfile{Name: "tp1", SubscriberIdentifier: "subscriber1",
+		ProfileType: "pt1", NumGemPorts: 1, Version: 1,
+		InstanceCtrl: tp.InstanceControl{Onu: "1", Uni: "1", MaxGemPayloadSize: "1"},
+	}
+	tprofile.UsScheduler.Direction = "UPSTREAM"
+	tprofile.UsScheduler.AdditionalBw = "AdditionalBW_None"
+	tprofile.UsScheduler.QSchedPolicy = "WRR"
+
+	tprofile2 := tprofile
+	tprofile2.DsScheduler.Direction = "DOWNSTREAM"
+	tprofile2.DsScheduler.AdditionalBw = "AdditionalBW_None"
+	tprofile2.DsScheduler.QSchedPolicy = "WRR"
+	//defTprofile := &tp.DefaultTechProfile{}
+	type args struct {
+		Dir     tp_pb.Direction
+		IntfID  uint32
+		OnuID   uint32
+		UniID   uint32
+		UniPort uint32
+		TpInst  *tp.TechProfile
+	}
+	tests := []struct {
+		name       string
+		schedQueue schedQueue
+		wantErr    bool
+	}{
+		// TODO: Add test cases.
+		{"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_UPSTREAM, 1, 1, 1, 64, 1, tprofile, 0, nil}, false},
+		{"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
+		// negative test cases
+		{"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
+		{"RemoveSchedulerQueues", schedQueue{tp_pb.Direction_DOWNSTREAM, 1, 1, 1, 65, 1, tprofile2, 0, nil}, false},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := flowMgr.RemoveSchedulerQueues(ctx, tt.schedQueue); (err != nil) != tt.wantErr {
+				t.Errorf("OpenOltFlowMgr.RemoveSchedulerQueues() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+
+}
+
+func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+	log.Debug("Info Warning Error: Starting RemoveFlow() test")
+	fa := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(2),
+			fu.Metadata_ofp(2),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+			fu.Output(1),
+		},
+	}
+	ofpstats := fu.MkFlowStat(fa)
+	ofpstats.Cookie = ofpstats.Id
+	lldpFa := &fu.FlowArgs{
+		KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1),
+			fu.EthType(0x88CC),
+			fu.TunnelId(536870912),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
+		},
+	}
+	lldpofpstats := fu.MkFlowStat(lldpFa)
+	//lldpofpstats.Cookie = lldpofpstats.Id
+
+	dhcpFa := &fu.FlowArgs{
+		KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1),
+			fu.UdpSrc(67),
+			//fu.TunnelId(536870912),
+			fu.IpProto(17),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
+		},
+	}
+	dhcpofpstats := fu.MkFlowStat(dhcpFa)
+	//dhcpofpstats.Cookie = dhcpofpstats.Id
+
+	//multicast flow
+	multicastFa := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(65536),
+			fu.VlanVid(660),             //vlan
+			fu.Metadata_ofp(uint64(66)), //inner vlan
+			fu.EthType(0x800),           //ipv4
+			fu.Ipv4Dst(3809869825),      //227.22.0.1
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Group(1),
+		},
+	}
+	multicastOfpStats := fu.MkFlowStat(multicastFa)
+	multicastOfpStats.Id = 1
+
+	type args struct {
+		flow *ofp.OfpFlowStats
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		{"RemoveFlow", args{flow: ofpstats}},
+		{"RemoveFlow", args{flow: lldpofpstats}},
+		{"RemoveFlow", args{flow: dhcpofpstats}},
+		{"RemoveFlow", args{flow: multicastOfpStats}},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			flowMgr.RemoveFlow(ctx, tt.args.flow)
+		})
+	}
+	// t.Error("=====")
+}
+
+func TestOpenOltFlowMgr_AddFlow(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+	kw := make(map[string]uint64)
+	kw["table_id"] = 1
+	kw["meter_id"] = 1
+	kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
+
+	// Upstream flow
+	fa := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(536870912),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
+			fu.Output(65536),
+			fu.PushVlan(0x8100),
+		},
+		KV: kw,
+	}
+
+	// Downstream flow
+	fa3 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(65536),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			//fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+			fu.PopVlan(),
+			fu.Output(536870912),
+		},
+		KV: kw,
+	}
+
+	fa2 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1000),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+			fu.Output(65533),
+		},
+		KV: kw,
+	}
+
+	// TODO Add LLDP flow
+	// TODO Add DHCP flow
+
+	// Flows for negative scenarios
+	// Failure in formulateActionInfoFromFlow()
+	fa4 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1000),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Experimenter(257, []byte{1, 2, 3, 4}),
+		},
+		KV: kw,
+	}
+
+	// Invalid Output
+	fa5 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1000),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Output(0),
+		},
+		KV: kw,
+	}
+
+	// Tech-Profile-ID update (not supported)
+	kw6 := make(map[string]uint64)
+	kw6["table_id"] = 1
+	kw6["meter_id"] = 1
+	kw6["write_metadata"] = 0x4100000000 // TpID Other than the stored one
+	fa6 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(536870912),
+			fu.TunnelId(16),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
+			fu.Output(65535),
+		},
+		KV: kw6,
+	}
+
+	lldpFa := &fu.FlowArgs{
+		KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1),
+			fu.EthType(0x88CC),
+			fu.TunnelId(536870912),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
+		},
+	}
+
+	dhcpFa := &fu.FlowArgs{
+		KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1),
+			fu.UdpSrc(67),
+			//fu.TunnelId(536870912),
+			fu.IpProto(17),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
+		},
+	}
+	igmpFa := &fu.FlowArgs{
+		KV: fu.OfpFlowModArgs{"priority": 1000, "cookie": 48132224281636694},
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(1),
+			fu.UdpSrc(67),
+			//fu.TunnelId(536870912),
+			fu.IpProto(2),
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
+		},
+	}
+
+	fa9 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(536870912),
+			fu.TunnelId(16),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+			fu.VlanPcp(1000),
+			fu.UdpDst(65535),
+			fu.UdpSrc(536870912),
+			fu.Ipv4Dst(65535),
+			fu.Ipv4Src(536870912),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
+			fu.Output(65535),
+		},
+		KV: kw6,
+	}
+
+	fa10 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(65533),
+			//	fu.TunnelId(16),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+			fu.VlanPcp(1000),
+			fu.UdpDst(65535),
+			fu.UdpSrc(536870912),
+			fu.Ipv4Dst(65535),
+			fu.Ipv4Src(536870912),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
+			fu.Output(65535),
+		},
+		KV: kw6,
+	}
+	//multicast flow
+	fa11 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(65536),
+			fu.VlanVid(660),             //vlan
+			fu.Metadata_ofp(uint64(66)), //inner vlan
+			fu.EthType(0x800),           //ipv4
+			fu.Ipv4Dst(3809869825),      //227.22.0.1
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Group(1),
+		},
+		KV: kw6,
+	}
+	ofpstats := fu.MkFlowStat(fa)
+	ofpstats2 := fu.MkFlowStat(fa2)
+	ofpstats3 := fu.MkFlowStat(fa3)
+	ofpstats4 := fu.MkFlowStat(fa4)
+	ofpstats5 := fu.MkFlowStat(fa5)
+	ofpstats6 := fu.MkFlowStat(fa6)
+	ofpstats7 := fu.MkFlowStat(lldpFa)
+	ofpstats8 := fu.MkFlowStat(dhcpFa)
+	ofpstats9 := fu.MkFlowStat(fa9)
+	ofpstats10 := fu.MkFlowStat(fa10)
+	igmpstats := fu.MkFlowStat(igmpFa)
+	ofpstats11 := fu.MkFlowStat(fa11)
+
+	fmt.Println(ofpstats6, ofpstats9, ofpstats10)
+
+	ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
+	flowMetadata := &voltha.FlowMetadata{
+		Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
+	}
+	type args struct {
+		flow         *ofp.OfpFlowStats
+		flowMetadata *voltha.FlowMetadata
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		{"AddFlow", args{flow: ofpstats, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: ofpstats2, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: ofpstats3, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: ofpstats4, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: ofpstats5, flowMetadata: flowMetadata}},
+		//{"AddFlow", args{flow: ofpstats6, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: ofpstats7, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: ofpstats8, flowMetadata: flowMetadata}},
+		//{"AddFlow", args{flow: ofpstats9, flowMetadata: flowMetadata}},
+		{"AddFlow", args{flow: igmpstats, flowMetadata: flowMetadata}},
+		//{"AddFlow", args{flow: ofpstats10, flowMetadata: flowMetadata}},
+		//ofpstats10
+		{"AddFlow", args{flow: ofpstats11, flowMetadata: flowMetadata}},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			flowMgr.AddFlow(ctx, tt.args.flow, tt.args.flowMetadata)
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_UpdateOnuInfo(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+	type args struct {
+		intfID    uint32
+		onuID     uint32
+		serialNum string
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		{"UpdateOnuInfo", args{1, 1, "onu1"}},
+		{"UpdateOnuInfo", args{2, 3, "onu1"}},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			flowMgr.UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_deleteGemPortFromLocalCache(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+	type args struct {
+		intfID                uint32
+		onuID                 uint32
+		gemPortIDs            []uint32
+		gemPortIDsToBeDeleted []uint32
+		serialNum             string
+		finalLength           int
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// Add/Delete single gem port
+		{"DeleteGemPortFromLocalCache1", args{0, 1, []uint32{1}, []uint32{1}, "onu1", 0}},
+		// Delete all gemports
+		{"DeleteGemPortFromLocalCache2", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4}, "onu1", 0}},
+		// Try to delete when there is no gem port
+		{"DeleteGemPortFromLocalCache3", args{0, 1, []uint32{}, []uint32{1, 2}, "onu1", 0}},
+		// Try to delete non-existent gem port
+		{"DeleteGemPortFromLocalCache4", args{0, 1, []uint32{1}, []uint32{2}, "onu1", 1}},
+		// Try to delete two of the gem ports
+		{"DeleteGemPortFromLocalCache5", args{0, 1, []uint32{1, 2, 3, 4}, []uint32{2, 4}, "onu1", 2}},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			flowMgr.UpdateOnuInfo(ctx, tt.args.intfID, tt.args.onuID, tt.args.serialNum)
+			for _, gemPort := range tt.args.gemPortIDs {
+				flowMgr.addGemPortToOnuInfoMap(ctx, tt.args.intfID, tt.args.onuID, gemPort)
+			}
+			for _, gemPortDeleted := range tt.args.gemPortIDsToBeDeleted {
+				flowMgr.deleteGemPortFromLocalCache(tt.args.intfID, tt.args.onuID, gemPortDeleted)
+			}
+			lenofGemPorts := len(flowMgr.onuGemInfo[tt.args.intfID][0].GemPorts)
+			if lenofGemPorts != tt.args.finalLength {
+				t.Errorf("GemPorts length is not as expected len = %d, want %d", lenofGemPorts, tt.args.finalLength)
+			}
+
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_GetLogicalPortFromPacketIn(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+	type args struct {
+		packetIn *openoltpb2.PacketIndication
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    uint32
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1, false},
+		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "nni", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 1048577, false},
+		// Negative Test cases.
+		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 2, GemportId: 1, FlowId: 100, PortNo: 1, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 0, true},
+		{"GetLogicalPortFromPacketIn", args{packetIn: &openoltpb2.PacketIndication{IntfType: "pon", IntfId: 1, GemportId: 1, FlowId: 100, PortNo: 0, Cookie: 100, Pkt: []byte("GetLogicalPortFromPacketIn")}}, 4112, false},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			got, err := flowMgr.GetLogicalPortFromPacketIn(ctx, tt.args.packetIn)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("OpenOltFlowMgr.GetLogicalPortFromPacketIn() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_GetPacketOutGemPortID(t *testing.T) {
+	// flwMgr := newMockFlowmgr()
+
+	type args struct {
+		intfID  uint32
+		onuID   uint32
+		portNum uint32
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    uint32
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"GetPacketOutGemPortID", args{intfID: 1, onuID: 1, portNum: 1}, 1, false},
+		{"GetPacketOutGemPortID", args{intfID: 2, onuID: 2, portNum: 2}, 2, false},
+		{"GetPacketOutGemPortID", args{intfID: 1, onuID: 2, portNum: 2}, 0, true},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			got, err := flowMgr.GetPacketOutGemPortID(ctx, tt.args.intfID, tt.args.onuID, tt.args.portNum)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("OpenOltFlowMgr.GetPacketOutGemPortID() = %v, want %v", got, tt.want)
+			}
+
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_DeleteTechProfileInstance(t *testing.T) {
+	// flwMgr := newMockFlowmgr()
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+		sn     string
+		tpID   uint32
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"DeleteTechProfileInstance", args{intfID: 0, onuID: 1, uniID: 1, sn: "", tpID: 64}, false},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := flowMgr.DeleteTechProfileInstance(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.sn, tt.args.tpID); (err != nil) != tt.wantErr {
+				t.Errorf("OpenOltFlowMgr.DeleteTechProfileInstance() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_checkAndAddFlow(t *testing.T) {
+	// flowMgr := newMockFlowmgr()
+	kw := make(map[string]uint64)
+	kw["table_id"] = 1
+	kw["meter_id"] = 1
+	kw["write_metadata"] = 0x4000000000 // Tech-Profile-ID 64
+
+	// Upstream flow
+	fa := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(536870912),
+			fu.Metadata_ofp(1),
+			fu.IpProto(17), // dhcp
+			fu.VlanPcp(0),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
+			fu.Output(65536),
+			fu.PushVlan(0x8100),
+		},
+		KV: kw,
+	}
+
+	// EAPOL
+	fa2 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(536870912),
+			fu.Metadata_ofp(1),
+			fu.EthType(0x888E),
+			fu.VlanPcp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 257)),
+			fu.Output(65536),
+			fu.PushVlan(0x8100),
+		},
+		KV: kw,
+	}
+
+	// HSIA
+	fa3 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(536870912),
+			fu.Metadata_ofp(1),
+			//fu.EthType(0x8100),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
+			fu.Output(65536),
+			fu.PushVlan(0x8100),
+		},
+		KV: kw,
+	}
+
+	fa4 := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(65535),
+			fu.Metadata_ofp(1),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
+			fu.VlanPcp(1),
+		},
+		Actions: []*ofp.OfpAction{
+			//fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
+			fu.Output(536870912),
+			fu.PopVlan(),
+		},
+		KV: kw,
+	}
+
+	classifierInfo := make(map[string]interface{})
+	actionInfo := make(map[string]interface{})
+	classifierInfo2 := make(map[string]interface{})
+	actionInfo2 := make(map[string]interface{})
+	classifierInfo3 := make(map[string]interface{})
+	actionInfo3 := make(map[string]interface{})
+	classifierInfo4 := make(map[string]interface{})
+	actionInfo4 := make(map[string]interface{})
+	flowState := fu.MkFlowStat(fa)
+	flowState2 := fu.MkFlowStat(fa2)
+	flowState3 := fu.MkFlowStat(fa3)
+	flowState4 := fu.MkFlowStat(fa4)
+	formulateClassifierInfoFromFlow(classifierInfo, flowState)
+	formulateClassifierInfoFromFlow(classifierInfo2, flowState2)
+	formulateClassifierInfoFromFlow(classifierInfo3, flowState3)
+	formulateClassifierInfoFromFlow(classifierInfo4, flowState4)
+
+	err := formulateActionInfoFromFlow(actionInfo, classifierInfo, flowState)
+	if err != nil {
+		// Error logging is already done in the called function
+		// So just return in case of error
+		return
+	}
+
+	err = formulateActionInfoFromFlow(actionInfo2, classifierInfo2, flowState2)
+	if err != nil {
+		// Error logging is already done in the called function
+		// So just return in case of error
+		return
+	}
+
+	err = formulateActionInfoFromFlow(actionInfo3, classifierInfo3, flowState3)
+	if err != nil {
+		// Error logging is already done in the called function
+		// So just return in case of error
+		return
+	}
+
+	err = formulateActionInfoFromFlow(actionInfo4, classifierInfo4, flowState4)
+	if err != nil {
+		// Error logging is already done in the called function
+		// So just return in case of error
+		return
+	}
+
+	//ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1}
+	//flowMetadata := &voltha.FlowMetadata{
+	//	Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
+	//}
+
+	TpInst := &tp.TechProfile{
+		Name:                 "Test-Tech-Profile",
+		SubscriberIdentifier: "257",
+		ProfileType:          "Mock",
+		Version:              1,
+		NumGemPorts:          4,
+		InstanceCtrl: tp.InstanceControl{
+			Onu: "1",
+			Uni: "16",
+		},
+	}
+
+	type fields struct {
+		techprofile   []tp.TechProfileIf
+		deviceHandler *DeviceHandler
+		resourceMgr   *rsrcMgr.OpenOltResourceMgr
+	}
+	type args struct {
+		args           map[string]uint32
+		classifierInfo map[string]interface{}
+		actionInfo     map[string]interface{}
+		flow           *ofp.OfpFlowStats
+		gemPort        uint32
+		intfID         uint32
+		onuID          uint32
+		uniID          uint32
+		portNo         uint32
+		TpInst         *tp.TechProfile
+		allocID        []uint32
+		gemPorts       []uint32
+		TpID           uint32
+		uni            string
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		{
+			name: "checkAndAddFlow-1",
+			args: args{
+				args:           nil,
+				classifierInfo: classifierInfo,
+				actionInfo:     actionInfo,
+				flow:           flowState,
+				gemPort:        1,
+				intfID:         1,
+				onuID:          1,
+				uniID:          16,
+				portNo:         1,
+				TpInst:         TpInst,
+				allocID:        []uint32{0x8001, 0x8002, 0x8003, 0x8004},
+				gemPorts:       []uint32{1, 2, 3, 4},
+				TpID:           64,
+				uni:            "16",
+			},
+		},
+		{
+			name: "checkAndAddFlow-2",
+			args: args{
+				args:           nil,
+				classifierInfo: classifierInfo2,
+				actionInfo:     actionInfo2,
+				flow:           flowState2,
+				gemPort:        1,
+				intfID:         1,
+				onuID:          1,
+				uniID:          16,
+				portNo:         1,
+				TpInst:         TpInst,
+				allocID:        []uint32{0x8001, 0x8002, 0x8003, 0x8004},
+				gemPorts:       []uint32{1, 2, 3, 4},
+				TpID:           64,
+				uni:            "16",
+			},
+		},
+		{
+			name: "checkAndAddFlow-3",
+			args: args{
+				args:           nil,
+				classifierInfo: classifierInfo3,
+				actionInfo:     actionInfo3,
+				flow:           flowState3,
+				gemPort:        1,
+				intfID:         1,
+				onuID:          1,
+				uniID:          16,
+				portNo:         1,
+				TpInst:         TpInst,
+				allocID:        []uint32{0x8001, 0x8002, 0x8003, 0x8004},
+				gemPorts:       []uint32{1, 2, 3, 4},
+				TpID:           64,
+				uni:            "16",
+			},
+		},
+		{
+			name: "checkAndAddFlow-4",
+			args: args{
+				args:           nil,
+				classifierInfo: classifierInfo4,
+				actionInfo:     actionInfo4,
+				flow:           flowState4,
+				gemPort:        1,
+				intfID:         1,
+				onuID:          1,
+				uniID:          16,
+				portNo:         1,
+				TpInst:         TpInst,
+				allocID:        []uint32{0x8001, 0x8002, 0x8003, 0x8004},
+				gemPorts:       []uint32{1, 2, 3, 4},
+				TpID:           64,
+				uni:            "16",
+			},
+		},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			flowMgr.checkAndAddFlow(ctx, tt.args.args, tt.args.classifierInfo, tt.args.actionInfo, tt.args.flow,
+				tt.args.TpInst, tt.args.gemPorts, tt.args.TpID, tt.args.uni)
+		})
+	}
+}
+
+func TestOpenOltFlowMgr_TestMulticastFlow(t *testing.T) {
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	//create group
+	group := newGroup(2, []uint32{1})
+	flowMgr.AddGroup(ctx, group)
+
+	//create multicast flow
+	multicastFlowArgs := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(65536),
+			fu.VlanVid(660),             //vlan
+			fu.Metadata_ofp(uint64(66)), //inner vlan
+			fu.EthType(0x800),           //ipv4
+			fu.Ipv4Dst(3809869825),      //227.22.0.1
+		},
+		Actions: []*ofp.OfpAction{
+			fu.Group(1),
+		},
+	}
+	ofpStats := fu.MkFlowStat(multicastFlowArgs)
+	flowMgr.AddFlow(ctx, ofpStats, &voltha.FlowMetadata{})
+
+	//add bucket to the group
+	group = newGroup(2, []uint32{1, 2})
+
+	flowMgr.ModifyGroup(ctx, group)
+}
diff --git a/internal/pkg/core/openolt_test.go b/internal/pkg/core/openolt_test.go
new file mode 100644
index 0000000..5944db2
--- /dev/null
+++ b/internal/pkg/core/openolt_test.go
@@ -0,0 +1,985 @@
+/*
+ * 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.
+ */
+
+/*
+This file contains unit test cases for functions in the file openolt.go.
+This file also implements the fields struct to mock the Openolt and few utility functions.
+*/
+
+//Package core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"context"
+	"errors"
+	com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-openolt-adapter/internal/pkg/config"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	"github.com/opencord/voltha-protos/v3/go/openflow_13"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"reflect"
+	"sync"
+	"testing"
+)
+
+// mocks the OpenOLT struct.
+type fields struct {
+	deviceHandlers        map[string]*DeviceHandler
+	coreProxy             *com.CoreProxy
+	adapterProxy          *com.AdapterProxy
+	eventProxy            *com.EventProxy
+	kafkaICProxy          kafka.InterContainerProxy
+	numOnus               int
+	KVStoreHost           string
+	KVStorePort           int
+	KVStoreType           string
+	exitChannel           chan int
+	lockDeviceHandlersMap sync.RWMutex
+	ctx                   context.Context
+}
+
+// mockOlt mocks OpenOLT struct.
+func mockOlt() *fields {
+	dh := newMockDeviceHandler()
+	newOlt := &fields{}
+	newOlt.deviceHandlers = map[string]*DeviceHandler{}
+	newOlt.deviceHandlers[dh.device.Id] = dh
+	return newOlt
+}
+
+// testOltObject maps fields type to OpenOLt type.
+func testOltObject(testOlt *fields) *OpenOLT {
+	return &OpenOLT{
+		deviceHandlers: testOlt.deviceHandlers,
+		coreProxy:      testOlt.coreProxy,
+		adapterProxy:   testOlt.adapterProxy,
+		eventProxy:     testOlt.eventProxy,
+		kafkaICProxy:   testOlt.kafkaICProxy,
+		numOnus:        testOlt.numOnus,
+		KVStoreHost:    testOlt.KVStoreHost,
+		KVStorePort:    testOlt.KVStorePort,
+		KVStoreType:    testOlt.KVStoreType,
+		exitChannel:    testOlt.exitChannel,
+	}
+}
+
+// mockDevice mocks Device.
+func mockDevice() *voltha.Device {
+	device := &voltha.Device{
+		Id:       "olt",
+		Root:     true,
+		ParentId: "logical_device",
+		Ports: []*voltha.Port{
+			{PortNo: 1, Label: "pon"},
+			{PortNo: 2, Label: "nni"},
+		},
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "olt",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+	}
+	return device
+}
+
+func TestNewOpenOLT(t *testing.T) {
+	tests := []struct {
+		name        string
+		fields      *fields
+		configFlags *config.AdapterFlags
+		want        *OpenOLT
+	}{
+		{"newopenolt-1", &fields{}, &config.AdapterFlags{OnuNumber: 1, KVStorePort: 1, KVStoreType: "consul", KVStoreHost: "1.1.1.1"},
+			&OpenOLT{numOnus: 1, KVStorePort: 1, KVStoreType: "consul", KVStoreHost: "1.1.1.1"}},
+		{"newopenolt-2", &fields{}, &config.AdapterFlags{OnuNumber: 2, KVStorePort: 2, KVStoreType: "etcd", KVStoreHost: "2.2.2.2"},
+			&OpenOLT{numOnus: 2, KVStorePort: 2, KVStoreType: "etcd", KVStoreHost: "2.2.2.2"}},
+		{"newopenolt-3", &fields{}, &config.AdapterFlags{OnuNumber: 3, KVStorePort: 3, KVStoreType: "consul", KVStoreHost: "3.3.3.3"},
+			&OpenOLT{numOnus: 3, KVStorePort: 3, KVStoreType: "consul", KVStoreHost: "3.3.3.3"}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NewOpenOLT(tt.fields.ctx, tt.fields.kafkaICProxy, tt.fields.coreProxy, tt.fields.adapterProxy,
+				tt.fields.eventProxy, tt.configFlags); reflect.TypeOf(got) != reflect.TypeOf(tt.want) && got != nil {
+				t.Errorf("NewOpenOLT() error = %v, wantErr %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Abandon_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"abandon_device-1", &fields{}, args{}, ErrNotImplemented},
+		{"abandon_device-2", &fields{}, args{}, ErrNotImplemented},
+		{"abandon_device-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Abandon_device(tt.args.device); err != tt.wantErr {
+				t.Errorf("Abandon_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Activate_image_update(t *testing.T) {
+	type args struct {
+		device  *voltha.Device
+		request *voltha.ImageDownload
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *voltha.ImageDownload
+		wantErr error
+	}{
+		{"activate_image_upate-1", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123XYZ"},
+			ErrNotImplemented},
+		{"activate_image_upate-2", &fields{}, args{}, &voltha.ImageDownload{Id: "Image2-ABC123CDE"},
+			ErrNotImplemented},
+		{"activate_image_upate-3", &fields{}, args{}, &voltha.ImageDownload{Id: "Image3-ABC123EFG"},
+			ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Activate_image_update(tt.args.device, tt.args.request)
+			if err != tt.wantErr && got == nil {
+				t.Errorf("Activate_image_update() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Adapter_descriptor(t *testing.T) {
+	tests := []struct {
+		name    string
+		fields  *fields
+		wantErr error
+	}{
+		{"adapter_descriptor-1", &fields{}, ErrNotImplemented},
+		{"adapter_descriptor-2", &fields{}, ErrNotImplemented},
+		{"adapter_descriptor-3", &fields{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Adapter_descriptor(); err != tt.wantErr {
+				t.Errorf("Adapter_descriptor() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Adopt_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	var device = mockDevice()
+	device.Id = "olt"
+	nilDevice := NewErrInvalidValue(log.Fields{"device": nil}, nil)
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"adopt_device-1", mockOlt(), args{}, nilDevice},
+		{"adopt_device-2", mockOlt(), args{device}, nilDevice},
+		{"adopt_device-3", mockOlt(), args{mockDevice()}, nil},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			err := oo.Adopt_device(tt.args.device)
+			if (err != nil) && (reflect.TypeOf(err) !=
+				reflect.TypeOf(tt.wantErr)) && (tt.args.device == nil) {
+				t.Errorf("Adopt_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+			if err == nil {
+				t.Log("return'd nil")
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Cancel_image_download(t *testing.T) {
+	type args struct {
+		device  *voltha.Device
+		request *voltha.ImageDownload
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *voltha.ImageDownload
+		wantErr error
+	}{
+		{"cancel_image_download-1", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123XYZ"},
+			ErrNotImplemented},
+		{"cancel_image_download-2", &fields{}, args{}, &voltha.ImageDownload{Id: "Image2-ABC123IJK"},
+			ErrNotImplemented},
+		{"cancel_image_download-3", &fields{}, args{}, &voltha.ImageDownload{Id: "Image3-ABC123KLM"},
+			ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Cancel_image_download(tt.args.device, tt.args.request)
+			if err != tt.wantErr && got == nil {
+				t.Errorf("Cancel_image_download() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Delete_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"delete_device-1", &fields{}, args{mockDevice()},
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Delete_device(tt.args.device); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Delete_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Device_types(t *testing.T) {
+	tests := []struct {
+		name    string
+		fields  *fields
+		want    *voltha.DeviceTypes
+		wantErr error
+	}{
+		{"device_types-1", &fields{}, &voltha.DeviceTypes{},
+			ErrNotImplemented},
+		{"device_types-2", &fields{}, &voltha.DeviceTypes{},
+			ErrNotImplemented},
+		{"device_types-3", &fields{}, &voltha.DeviceTypes{},
+			ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Device_types()
+			if err != tt.wantErr && got == nil {
+				t.Errorf("Device_types() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Disable_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"disable_device-1", mockOlt(), args{mockDevice()}, nil},
+		{"disable_device-2", &fields{}, args{mockDevice()},
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Disable_device(tt.args.device); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Disable_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Download_image(t *testing.T) {
+	type args struct {
+		device  *voltha.Device
+		request *voltha.ImageDownload
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *voltha.ImageDownload
+		wantErr error
+	}{
+		{"download_image-1", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123XYZ"},
+			ErrNotImplemented},
+		{"download_image-2", &fields{}, args{}, &voltha.ImageDownload{Id: "Image2-ABC123LKJ"},
+			ErrNotImplemented},
+		{"download_image-3", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123RTY"},
+			ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Download_image(tt.args.device, tt.args.request)
+			if err != tt.wantErr && got == nil {
+				t.Errorf("Download_image() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Get_device_details(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"get_device_details-1", &fields{}, args{}, ErrNotImplemented},
+		{"get_device_details-2", &fields{}, args{}, ErrNotImplemented},
+		{"get_device_details-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Get_device_details(tt.args.device); err != tt.wantErr {
+				t.Errorf("Get_device_details() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Get_image_download_status(t *testing.T) {
+	type args struct {
+		device  *voltha.Device
+		request *voltha.ImageDownload
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *voltha.ImageDownload
+		wantErr error
+	}{
+		{"get_image_download_status-1", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123XYZ"},
+			ErrNotImplemented},
+		{"get_image_download_status-2", &fields{}, args{}, &voltha.ImageDownload{Id: "Image2-ABC123LKJ"},
+			ErrNotImplemented},
+		{"get_image_download_status-3", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123DFG"},
+			ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Get_image_download_status(tt.args.device, tt.args.request)
+			if err != tt.wantErr && got == nil {
+				t.Errorf("Get_image_download_status() got = %v want = %v error = %v, wantErr %v",
+					got, tt.want, err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Get_ofp_device_info(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *ic.SwitchCapability
+		wantErr error
+	}{
+		{"get_ofp_device_info-1", mockOlt(), args{mockDevice()}, &ic.SwitchCapability{
+			Desc: &openflow_13.OfpDesc{
+				MfrDesc: "VOLTHA Project",
+				HwDesc:  "open_pon",
+				SwDesc:  "open_pon",
+			},
+			SwitchFeatures: &openflow_13.OfpSwitchFeatures{
+				NBuffers:     uint32(256),
+				NTables:      uint32(2),
+				Capabilities: uint32(15),
+			},
+		}, nil},
+		{"get_ofp_device_info-2", &fields{}, args{mockDevice()}, nil,
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Get_ofp_device_info(tt.args.device)
+			if !reflect.DeepEqual(err, tt.wantErr) || !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Get_ofp_device_info() got = %v want = %v error = %v, wantErr = %v",
+					got, tt.want, err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Get_ofp_port_info(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+		portNo int64
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *ic.PortCapability
+		wantErr error
+	}{
+		{"get_ofp_port_info-1", mockOlt(), args{mockDevice(), 1}, &ic.PortCapability{
+			Port: &voltha.LogicalPort{
+				DeviceId:     "olt",
+				DevicePortNo: uint32(1),
+				OfpPort: &openflow_13.OfpPort{
+					HwAddr:     []uint32{1, 2, 3, 4, 5, 6},
+					State:      uint32(4),
+					Curr:       uint32(4128),
+					Advertised: uint32(4128),
+					Peer:       uint32(4128),
+					CurrSpeed:  uint32(32),
+					MaxSpeed:   uint32(32),
+				},
+			},
+		}, nil},
+		{"get_ofp_port_info-2", &fields{}, args{mockDevice(), 1}, nil,
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Get_ofp_port_info(tt.args.device, tt.args.portNo)
+			if !reflect.DeepEqual(err, tt.wantErr) || !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Get_ofp_port_info() got = %v want = %v error = %v, wantErr = %v",
+					got, tt.want, err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Health(t *testing.T) {
+	tests := []struct {
+		name    string
+		fields  *fields
+		want    *voltha.HealthStatus
+		wantErr error
+	}{
+		{"health-1", &fields{}, &voltha.HealthStatus{}, ErrNotImplemented},
+		{"health-2", &fields{}, &voltha.HealthStatus{}, ErrNotImplemented},
+		{"health-3", &fields{}, &voltha.HealthStatus{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Health()
+			if err != tt.wantErr && got == nil {
+				t.Errorf("Get_ofp_port_info() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Process_inter_adapter_message(t *testing.T) {
+	type args struct {
+		msg *ic.InterAdapterMessage
+	}
+	var message1 = args{
+		msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:            "olt",
+				ProxyDeviceId: "",
+				ToDeviceId:    "onu1",
+			},
+		},
+	}
+	var message2 = args{
+		msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:            "olt",
+				ProxyDeviceId: "olt",
+				ToDeviceId:    "olt",
+				Type:          ic.InterAdapterMessageType_OMCI_REQUEST,
+			},
+		},
+	}
+	var message3 = args{
+		msg: &ic.InterAdapterMessage{
+			Header: &ic.InterAdapterHeader{
+				Id:            "olt",
+				ProxyDeviceId: "olt",
+				ToDeviceId:    "olt",
+				Type:          ic.InterAdapterMessageType_FLOW_REQUEST,
+			},
+		},
+	}
+	tests := []struct {
+		name        string
+		fields      *fields
+		args        args
+		wantErrType reflect.Type
+	}{
+		{"process_inter_adaptor_messgae-1", mockOlt(), message1,
+			reflect.TypeOf(&ErrNotFound{})},
+		{"process_inter_adaptor_messgae-2", mockOlt(), message2,
+			reflect.TypeOf(errors.New("message is nil"))},
+		{"process_inter_adaptor_messgae-3", mockOlt(), message3,
+			reflect.TypeOf(&ErrInvalidValue{})},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Process_inter_adapter_message(tt.args.msg); reflect.TypeOf(err) != tt.wantErrType {
+				t.Errorf("Process_inter_adapter_message() error = %v, wantErr %v",
+					reflect.TypeOf(err), tt.wantErrType)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Reboot_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"reboot_device-1", mockOlt(), args{mockDevice()}, nil},
+		{"reboot_device-2", &fields{}, args{mockDevice()},
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Reboot_device(tt.args.device); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Reboot_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Receive_packet_out(t *testing.T) {
+	acts := []*ofp.OfpAction{
+		fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA))),
+		fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+		fu.Output(1),
+	}
+	type args struct {
+		deviceID     string
+		egressPortNo int
+		packet       *openflow_13.OfpPacketOut
+	}
+	pktout := &ofp.OfpPacketOut{BufferId: 0, InPort: 1, Actions: acts, Data: []byte("AYDCAAAOAODsSE5TiMwCBwQA4OxITlIEBQUwLzUx" +
+		"BgIAFAgEMC81MQoJbG9jYWxob3N0EBwFAawbqqACAAAAoRAxLjMuNi4xLjQuMS40NDEz/gYAgMILAgD+GQCAwgkDAAAAAGQAAAAAAAAAAgICAgICAgL+" +
+		"GQCAwgoDAAAAAGQAAAAAAAAAAgICAgICAgIAAA==")}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"receive_packet_out-1", mockOlt(), args{mockDevice().Id, 1, pktout}, nil},
+		{"receive_packet_out-2", mockOlt(), args{"1234", 1, pktout},
+			NewErrNotFound("device-handler", log.Fields{"device-id": "1234"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Receive_packet_out(tt.args.deviceID, tt.args.egressPortNo, tt.args.packet); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Receive_packet_out() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Reconcile_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	expectedError := NewErrInvalidValue(log.Fields{"device": nil}, nil)
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"reconcile_device-1", &fields{}, args{}, expectedError},
+		{"reconcile_device-2", &fields{}, args{}, expectedError},
+		{"reconcile_device-3", &fields{}, args{}, expectedError},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Reconcile_device(tt.args.device); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Reconcile_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Reenable_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"reenable_device-1", mockOlt(), args{mockDevice()}, nil},
+		{"reenable_device-2", &fields{}, args{mockDevice()},
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Reenable_device(tt.args.device); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Reenable_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Revert_image_update(t *testing.T) {
+	type args struct {
+		device  *voltha.Device
+		request *voltha.ImageDownload
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *voltha.ImageDownload
+		wantErr error
+	}{
+		{"revert_image_update-1", &fields{}, args{}, &voltha.ImageDownload{Id: "Image1-ABC123XYZ"},
+			ErrNotImplemented},
+		{"revert_image_update-2", &fields{}, args{}, &voltha.ImageDownload{Id: "Image2-ABC123TYU"},
+			ErrNotImplemented},
+		{"revert_image_update-3", &fields{}, args{}, &voltha.ImageDownload{Id: "Image3-ABC123GTH"},
+			ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			got, err := oo.Revert_image_update(tt.args.device, tt.args.request)
+			if err != tt.wantErr && got == nil {
+				t.Log("error :", err)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Self_test_device(t *testing.T) {
+	type args struct {
+		device *voltha.Device
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"self_test_device-1", &fields{}, args{}, ErrNotImplemented},
+		{"self_test_device-2", &fields{}, args{}, ErrNotImplemented},
+		{"self_test_device-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Self_test_device(tt.args.device); err != tt.wantErr {
+				t.Errorf("Self_test_device() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Start(t *testing.T) {
+	type args struct {
+		ctx context.Context
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"start-1", &fields{}, args{}, errors.New("start error")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Start(tt.args.ctx); err != nil {
+				t.Errorf("Start() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Stop(t *testing.T) {
+	type args struct {
+		ctx context.Context
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"stop-1", &fields{exitChannel: make(chan int, 1)}, args{}, errors.New("stop error")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			oo.Start(tt.args.ctx)
+			if err := oo.Stop(tt.args.ctx); err != nil {
+				t.Errorf("Stop() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Suppress_event(t *testing.T) {
+	type args struct {
+		filter *voltha.EventFilter
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"suppress_event-1", &fields{}, args{}, ErrNotImplemented},
+		{"suppress_event-2", &fields{}, args{}, ErrNotImplemented},
+		{"suppress_event-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Suppress_event(tt.args.filter); err != tt.wantErr {
+				t.Errorf("Suppress_event() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Unsuppress_event(t *testing.T) {
+	type args struct {
+		filter *voltha.EventFilter
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"unsupress_event-1", &fields{}, args{}, ErrNotImplemented},
+		{"unsupress_event-2", &fields{}, args{}, ErrNotImplemented},
+		{"unsupress_event-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Unsuppress_event(tt.args.filter); err != tt.wantErr {
+				t.Errorf("Unsuppress_event() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Update_flows_bulk(t *testing.T) {
+	type args struct {
+		device       *voltha.Device
+		flows        *voltha.Flows
+		groups       *voltha.FlowGroups
+		flowMetadata *voltha.FlowMetadata
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"update_flows_bulk-1", &fields{}, args{}, ErrNotImplemented},
+		{"update_flows_bulk-2", &fields{}, args{}, ErrNotImplemented},
+		{"update_flows_bulk-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Update_flows_bulk(tt.args.device, tt.args.flows, tt.args.groups, tt.args.flowMetadata); err != tt.wantErr {
+				t.Errorf("Update_flows_bulk() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Update_flows_incrementally(t *testing.T) {
+	type args struct {
+		device       *voltha.Device
+		flows        *openflow_13.FlowChanges
+		groups       *openflow_13.FlowGroupChanges
+		flowMetadata *voltha.FlowMetadata
+	}
+
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"update_flows_incrementally-1", &fields{}, args{device: mockDevice()},
+			NewErrNotFound("device-handler", log.Fields{"device-id": "olt"}, nil)},
+		{"update_flows_incrementally-2", mockOlt(), args{device: mockDevice()}, nil},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Update_flows_incrementally(tt.args.device, tt.args.flows, tt.args.groups, tt.args.flowMetadata); !reflect.DeepEqual(err, tt.wantErr) {
+				t.Errorf("Update_flows_incrementally() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Update_pm_config(t *testing.T) {
+	type args struct {
+		device    *voltha.Device
+		pmConfigs *voltha.PmConfigs
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"update_pm_config-1", &fields{}, args{}, ErrNotImplemented},
+		{"update_pm_config-2", &fields{}, args{}, ErrNotImplemented},
+		{"update_pm_config-3", &fields{}, args{}, ErrNotImplemented},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Update_pm_config(tt.args.device, tt.args.pmConfigs); err != tt.wantErr {
+				t.Errorf("Update_pm_config() error = %v, wantErr %v", err, tt.wantErr)
+			}
+
+		})
+	}
+}
+
+func TestOpenOLT_deleteDeviceHandlerToMap(t *testing.T) {
+	type args struct {
+		agent *DeviceHandler
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+	}{
+		{"delete_device_handler_map-1", mockOlt(), args{newMockDeviceHandler()}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			oo.deleteDeviceHandlerToMap(tt.args.agent)
+			if len(oo.deviceHandlers) > 0 {
+				t.Errorf("delete device manager failed")
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Enable_port(t *testing.T) {
+	type args struct {
+		deviceID string
+		port     *voltha.Port
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"Enable_port-1", mockOlt(), args{deviceID: "olt", port: &voltha.Port{Type: voltha.Port_PON_OLT, PortNo: 1}}, false},
+		{"Enable_port-2", mockOlt(), args{deviceID: "olt", port: &voltha.Port{Type: voltha.Port_ETHERNET_NNI, PortNo: 1}}, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Enable_port(tt.args.deviceID, tt.args.port); (err != nil) != tt.wantErr {
+				t.Errorf("OpenOLT.Enable_port() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOLT_Disable_port(t *testing.T) {
+	type args struct {
+		deviceID string
+		port     *voltha.Port
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"Disable_port-1", mockOlt(), args{deviceID: "olt", port: &voltha.Port{Type: voltha.Port_PON_OLT, PortNo: 1}}, false},
+		{"Disable_port-2", mockOlt(), args{deviceID: "olt", port: &voltha.Port{Type: voltha.Port_ETHERNET_NNI, PortNo: 1}}, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oo := testOltObject(tt.fields)
+			if err := oo.Disable_port(tt.args.deviceID, tt.args.port); (err != nil) != tt.wantErr {
+				t.Errorf("OpenOLT.Disable_port() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/core/statsmanager.go b/internal/pkg/core/statsmanager.go
new file mode 100755
index 0000000..3133bce
--- /dev/null
+++ b/internal/pkg/core/statsmanager.go
@@ -0,0 +1,486 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"fmt"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-protos/v3/go/openolt"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+	"sync"
+	"time"
+)
+
+var mutex = &sync.Mutex{}
+
+// PonPort representation
+type PonPort struct {
+	/*
+	   This is a highly reduced version taken from the adtran pon_port.
+	   TODO: Extend for use in the openolt adapter set.
+	*/
+	/*    MAX_ONUS_SUPPORTED = 256
+	      DEFAULT_ENABLED = False
+	      MAX_DEPLOYMENT_RANGE = 25000  # Meters (OLT-PB maximum)
+
+	      _MCAST_ONU_ID = 253
+	      _MCAST_ALLOC_BASE = 0x500
+
+	      _SUPPORTED_ACTIVATION_METHODS = ['autodiscovery']  # , 'autoactivate']
+	      _SUPPORTED_AUTHENTICATION_METHODS = ['serial-number']
+	*/
+	PONID    uint32
+	DeviceID string
+	IntfID   uint32
+	PortNum  uint32
+	PortID   uint32
+	Label    string
+	ONUs     map[uint32]interface{}
+	ONUsByID map[uint32]interface{}
+
+	RxBytes        uint64
+	RxPackets      uint64
+	RxUcastPackets uint64
+	RxMcastPackets uint64
+	RxBcastPackets uint64
+	RxErrorPackets uint64
+	TxBytes        uint64
+	TxPackets      uint64
+	TxUcastPackets uint64
+	TxMcastPackets uint64
+	TxBcastPackets uint64
+	TxErrorPackets uint64
+	RxCrcErrors    uint64
+	BipErrors      uint64
+}
+
+// NewPONPort returns a new instance of PonPort initialized with given PONID, DeviceID, IntfID and PortNum
+func NewPONPort(PONID uint32, DeviceID string, IntfID uint32, PortNum uint32) *PonPort {
+
+	var PON PonPort
+
+	PON.PONID = PONID
+	PON.DeviceID = DeviceID
+	PON.IntfID = IntfID
+	PON.PortNum = PortNum
+	PON.PortID = 0
+	PON.Label = fmt.Sprintf("%s%d", "pon-", PONID)
+
+	PON.ONUs = make(map[uint32]interface{})
+	PON.ONUsByID = make(map[uint32]interface{})
+
+	/*
+	   Statistics  taken from nni_port
+	   self.intf_id = 0  #handled by getter
+	   self.port_no = 0  #handled by getter
+	   self.port_id = 0  #handled by getter
+
+	   Note:  In the current implementation of the kpis coming from the BAL the stats are the
+	   samne model for NNI and PON.
+
+	   TODO:   Integrate additional kpis for the PON and other southbound port objecgts.
+
+	*/
+
+	PON.RxBytes = 0
+	PON.RxPackets = 0
+	PON.RxUcastPackets = 0
+	PON.RxMcastPackets = 0
+	PON.RxBcastPackets = 0
+	PON.RxErrorPackets = 0
+	PON.TxBytes = 0
+	PON.TxPackets = 0
+	PON.TxUcastPackets = 0
+	PON.TxMcastPackets = 0
+	PON.TxBcastPackets = 0
+	PON.TxErrorPackets = 0
+	PON.RxCrcErrors = 0
+	PON.BipErrors = 0
+
+	/*    def __str__(self):
+	      return "PonPort-{}: Admin: {}, Oper: {}, OLT: {}".format(self._label,
+	                                                               self._admin_state,
+	                                                               self._oper_status,
+	                                                               self.olt)
+	*/
+	return &PON
+}
+
+// NniPort representation
+type NniPort struct {
+	/*
+	   Northbound network port, often Ethernet-based
+
+	   This is a highly reduced version taken from the adtran nni_port code set
+	   TODO:   add functions to allow for port specific values and operations
+	*/
+	PortNum     uint32
+	Name        string
+	LogicalPort uint32
+	IntfID      uint32
+
+	RxBytes        uint64
+	RxPackets      uint64
+	RxUcastPackets uint64
+	RxMcastPackets uint64
+	RxBcastPackets uint64
+	RxErrorPackets uint64
+	TxBytes        uint64
+	TxPackets      uint64
+	TxUcastPackets uint64
+	TxMcastPackets uint64
+	TxBcastPackets uint64
+	TxErrorPackets uint64
+	RxCrcErrors    uint64
+	BipErrors      uint64
+}
+
+// NewNniPort returns a new instance of NniPort initialized with the given PortNum and IntfID
+func NewNniPort(PortNum uint32, IntfID uint32) *NniPort {
+
+	var NNI NniPort
+
+	NNI.PortNum = PortNum
+	NNI.Name = fmt.Sprintf("%s%d", "nni-", PortNum)
+	NNI.IntfID = IntfID
+
+	NNI.RxBytes = 0
+	NNI.RxPackets = 0
+	NNI.RxUcastPackets = 0
+	NNI.RxMcastPackets = 0
+	NNI.RxBcastPackets = 0
+	NNI.RxErrorPackets = 0
+	NNI.TxBytes = 0
+	NNI.TxPackets = 0
+	NNI.TxUcastPackets = 0
+	NNI.TxMcastPackets = 0
+	NNI.TxBcastPackets = 0
+	NNI.TxErrorPackets = 0
+	NNI.RxCrcErrors = 0
+	NNI.BipErrors = 0
+
+	return &NNI
+}
+
+// OpenOltStatisticsMgr structure
+type OpenOltStatisticsMgr struct {
+	Device         *DeviceHandler
+	NorthBoundPort map[uint32]*NniPort
+	SouthBoundPort map[uint32]*PonPort
+	// TODO  PMMetrics Metrics
+}
+
+// NewOpenOltStatsMgr returns a new instance of the OpenOltStatisticsMgr
+func NewOpenOltStatsMgr(Dev *DeviceHandler) *OpenOltStatisticsMgr {
+
+	var StatMgr OpenOltStatisticsMgr
+
+	StatMgr.Device = Dev
+	// TODO call metric PMMetric =
+	// Northbound and Southbound ports
+	// added to initialize the pm_metrics
+	var Ports interface{}
+	Ports, _ = InitPorts("nni", Dev.deviceID, 1)
+	StatMgr.NorthBoundPort, _ = Ports.(map[uint32]*NniPort)
+	NumPonPorts := Dev.resourceMgr.DevInfo.GetPonPorts()
+	Ports, _ = InitPorts("pon", Dev.deviceID, NumPonPorts)
+	StatMgr.SouthBoundPort, _ = Ports.(map[uint32]*PonPort)
+	return &StatMgr
+}
+
+// InitPorts collects the port objects:  nni and pon that are updated with the current data from the OLT
+func InitPorts(Intftype string, DeviceID string, numOfPorts uint32) (interface{}, error) {
+	/*
+	     This method collects the port objects:  nni and pon that are updated with the
+	     current data from the OLT
+
+	     Both the northbound (nni) and southbound ports are indexed by the interface id (intf_id)
+	     and NOT the port number. When the port object is instantiated it will contain the intf_id and
+	     port_no values
+
+	   :param type:
+	   :return:
+	*/
+	var i uint32
+	if Intftype == "nni" {
+		NniPorts := make(map[uint32]*NniPort)
+		for i = 0; i < numOfPorts; i++ {
+			Port := BuildPortObject(i, "nni", DeviceID).(*NniPort)
+			NniPorts[Port.IntfID] = Port
+		}
+		return NniPorts, nil
+	} else if Intftype == "pon" {
+		PONPorts := make(map[uint32]*PonPort)
+		for i = 0; i < numOfPorts; i++ {
+			PONPort := BuildPortObject(i, "pon", DeviceID).(*PonPort)
+			PONPorts[PortNoToIntfID(PONPort.IntfID, voltha.Port_PON_OLT)] = PONPort
+		}
+		return PONPorts, nil
+	} else {
+		log.Errorf("Invalid type of interface %s", Intftype)
+		return nil, NewErrInvalidValue(log.Fields{"interface-type": Intftype}, nil)
+	}
+}
+
+// BuildPortObject allows for updating north and southbound ports, newly discovered ports, and devices
+func BuildPortObject(PortNum uint32, IntfType string, DeviceID string) interface{} {
+	/*
+	   Separate method to allow for updating north and southbound ports
+	   newly discovered ports and devices
+
+	   :param port_num:
+	   :param type:
+	   :return:
+	*/
+
+	//This builds a port object which is added to the
+	//appropriate northbound or southbound values
+	if IntfType == "nni" {
+		IntfID := IntfIDToPortNo(PortNum, voltha.Port_ETHERNET_NNI)
+		nniID := PortNoToIntfID(IntfID, voltha.Port_ETHERNET_NNI)
+		log.Debugf("NniID %v", nniID)
+		return NewNniPort(PortNum, nniID)
+	} else if IntfType == "pon" {
+		// PON ports require a different configuration
+		//  intf_id and pon_id are currently equal.
+		IntfID := IntfIDToPortNo(PortNum, voltha.Port_PON_OLT)
+		PONID := PortNoToIntfID(IntfID, voltha.Port_PON_OLT)
+		log.Debugf("PonID %v", PONID)
+		return NewPONPort(PONID, DeviceID, IntfID, PortNum)
+	} else {
+		log.Errorf("Invalid type of interface %s", IntfType)
+		return nil
+	}
+}
+
+// collectNNIMetrics will collect the nni port metrics
+func (StatMgr *OpenOltStatisticsMgr) collectNNIMetrics(nniID uint32) map[string]float32 {
+
+	nnival := make(map[string]float32)
+	mutex.Lock()
+	cm := StatMgr.Device.portStats.NorthBoundPort[nniID]
+	mutex.Unlock()
+	metricName := StatMgr.Device.metrics.GetSubscriberMetrics()
+
+	if metricName != nil && len(metricName) > 0 {
+		for mName := range metricName {
+			switch mName {
+			case "rx_bytes":
+				nnival["RxBytes"] = float32(cm.RxBytes)
+			case "rx_packets":
+				nnival["RxPackets"] = float32(cm.RxPackets)
+			case "rx_ucast_packets":
+				nnival["RxUcastPackets"] = float32(cm.RxUcastPackets)
+			case "rx_mcast_packets":
+				nnival["RxMcastPackets"] = float32(cm.RxMcastPackets)
+			case "rx_bcast_packets":
+				nnival["RxBcastPackets"] = float32(cm.RxBcastPackets)
+			case "tx_bytes":
+				nnival["TxBytes"] = float32(cm.TxBytes)
+			case "tx_packets":
+				nnival["TxPackets"] = float32(cm.TxPackets)
+			case "tx_mcast_packets":
+				nnival["TxMcastPackets"] = float32(cm.TxMcastPackets)
+			case "tx_bcast_packets":
+				nnival["TxBcastPackets"] = float32(cm.TxBcastPackets)
+			}
+		}
+	}
+	return nnival
+}
+
+// collectPONMetrics will collect the pon port metrics
+func (StatMgr *OpenOltStatisticsMgr) collectPONMetrics(pID uint32) map[string]float32 {
+
+	ponval := make(map[string]float32)
+	mutex.Lock()
+	cm := StatMgr.Device.portStats.SouthBoundPort[pID]
+	mutex.Unlock()
+	metricName := StatMgr.Device.metrics.GetSubscriberMetrics()
+
+	if metricName != nil && len(metricName) > 0 {
+		for mName := range metricName {
+			switch mName {
+			case "rx_bytes":
+				ponval["RxBytes"] = float32(cm.RxBytes)
+			case "rx_packets":
+				ponval["RxPackets"] = float32(cm.RxPackets)
+			// these are not supported in OpenOlt Agent now
+			// will return zero until supported
+			case "rx_ucast_packets":
+				ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
+			case "rx_mcast_packets":
+				ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
+			case "rx_bcast_packets":
+				ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
+			// End will return zero until supported
+			case "tx_bytes":
+				ponval["TxBytes"] = float32(cm.TxBytes)
+			case "tx_packets":
+				ponval["TxPackets"] = float32(cm.TxPackets)
+			// these are not supported in OpenOlt Agent now
+			// will return zero until supported
+			case "tx_ucast_packets":
+				ponval["TxUcastPackets"] = float32(cm.TxUcastPackets)
+			case "tx_mcast_packets":
+				ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
+			case "tx_bcast_packets":
+				ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
+			}
+		}
+	}
+	return ponval
+}
+
+// publishMatrics will publish the pon port metrics
+func (StatMgr OpenOltStatisticsMgr) publishMetrics(portType string, val map[string]float32, portnum uint32, context map[string]string, devID string) {
+	log.Debugf("Post-%v %v", portType, val)
+
+	var metricInfo voltha.MetricInformation
+	var ke voltha.KpiEvent2
+	var volthaEventSubCatgry voltha.EventSubCategory_Types
+
+	if portType == "NNIStats" {
+		volthaEventSubCatgry = voltha.EventSubCategory_NNI
+	} else {
+		volthaEventSubCatgry = voltha.EventSubCategory_PON
+	}
+
+	raisedTs := time.Now().UnixNano()
+	mmd := voltha.MetricMetaData{
+		Title:    portType,
+		Ts:       float64(raisedTs),
+		Context:  context,
+		DeviceId: devID,
+	}
+
+	metricInfo.Metadata = &mmd
+	metricInfo.Metrics = val
+
+	ke.SliceData = []*voltha.MetricInformation{&metricInfo}
+	ke.Type = voltha.KpiEventType_slice
+	ke.Ts = float64(time.Now().UnixNano())
+
+	if err := StatMgr.Device.EventProxy.SendKpiEvent("STATS_EVENT", &ke, voltha.EventCategory_EQUIPMENT, volthaEventSubCatgry, raisedTs); err != nil {
+		log.Errorw("Failed to send Pon stats", log.Fields{"err": err})
+	}
+
+}
+
+// PortStatisticsIndication handles the port statistics indication
+func (StatMgr *OpenOltStatisticsMgr) PortStatisticsIndication(PortStats *openolt.PortStatistics, NumPonPorts uint32) {
+	log.Debugf("port-stats-collected %v", PortStats)
+	StatMgr.PortsStatisticsKpis(PortStats, NumPonPorts)
+	log.Infow("Received port stats indication", log.Fields{"PortStats": PortStats})
+	// TODO send stats to core topic to the voltha kafka or a different kafka ?
+}
+
+// FlowStatisticsIndication to be implemented
+func FlowStatisticsIndication(self, FlowStats *openolt.FlowStatistics) {
+	log.Debugf("flow-stats-collected %v", FlowStats)
+	//TODO send to kafka ?
+}
+
+// PortsStatisticsKpis map the port stats values into a dictionary, creates the kpiEvent and then publish to Kafka
+func (StatMgr *OpenOltStatisticsMgr) PortsStatisticsKpis(PortStats *openolt.PortStatistics, NumPonPorts uint32) {
+
+	/*map the port stats values into a dictionary
+	  Create a kpoEvent and publish to Kafka
+
+	  :param port_stats:
+	  :return:
+	*/
+	//var err error
+	IntfID := PortStats.IntfId
+
+	if (IntfIDToPortNo(1, voltha.Port_ETHERNET_NNI) < IntfID) &&
+		(IntfID < IntfIDToPortNo(4, voltha.Port_ETHERNET_NNI)) {
+		/*
+		   for this release we are only interested in the first NNI for
+		   Northbound.
+		   we are not using the other 3
+		*/
+		return
+	} else if IntfIDToPortNo(0, voltha.Port_ETHERNET_NNI) == IntfID {
+
+		var portNNIStat NniPort
+		portNNIStat.IntfID = IntfID
+		portNNIStat.PortNum = uint32(0)
+		portNNIStat.RxBytes = PortStats.RxBytes
+		portNNIStat.RxPackets = PortStats.RxPackets
+		portNNIStat.RxUcastPackets = PortStats.RxUcastPackets
+		portNNIStat.RxMcastPackets = PortStats.RxMcastPackets
+		portNNIStat.RxBcastPackets = PortStats.RxBcastPackets
+		portNNIStat.TxBytes = PortStats.TxBytes
+		portNNIStat.TxPackets = PortStats.TxPackets
+		portNNIStat.TxUcastPackets = PortStats.TxUcastPackets
+		portNNIStat.TxMcastPackets = PortStats.TxMcastPackets
+		portNNIStat.TxBcastPackets = PortStats.TxBcastPackets
+		mutex.Lock()
+		StatMgr.NorthBoundPort[0] = &portNNIStat
+		mutex.Unlock()
+		log.Debugf("Received-NNI-Stats: %v", StatMgr.NorthBoundPort)
+	}
+	for i := uint32(0); i < NumPonPorts; i++ {
+
+		if IntfIDToPortNo(i, voltha.Port_PON_OLT) == IntfID {
+			var portPonStat PonPort
+			portPonStat.IntfID = IntfID
+			portPonStat.PortNum = i
+			portPonStat.PONID = i
+			portPonStat.RxBytes = PortStats.RxBytes
+			portPonStat.RxPackets = PortStats.RxPackets
+			portPonStat.RxUcastPackets = PortStats.RxUcastPackets
+			portPonStat.RxMcastPackets = PortStats.RxMcastPackets
+			portPonStat.RxBcastPackets = PortStats.RxBcastPackets
+			portPonStat.TxBytes = PortStats.TxBytes
+			portPonStat.TxPackets = PortStats.TxPackets
+			portPonStat.TxUcastPackets = PortStats.TxUcastPackets
+			portPonStat.TxMcastPackets = PortStats.TxMcastPackets
+			portPonStat.TxBcastPackets = PortStats.TxBcastPackets
+			mutex.Lock()
+			StatMgr.SouthBoundPort[i] = &portPonStat
+			mutex.Unlock()
+			log.Debugf("Received-PON-Stats-for-Port %v : %v", i, StatMgr.SouthBoundPort[i])
+		}
+	}
+
+	/*
+	   Based upon the intf_id map to an nni port or a pon port
+	   the intf_id is the key to the north or south bound collections
+
+	   Based upon the intf_id the port object (nni_port or pon_port) will
+	   have its data attr. updated by the current dataset collected.
+
+	   For prefixing the rule is currently to use the port number and not the intf_id
+	*/
+	//FIXME : Just use first NNI for now
+	/* TODO should the data be marshaled before sending it ?
+	   if IntfID == IntfIdToPortNo(0, voltha.Port_ETHERNET_NNI) {
+	       //NNI port (just the first one)
+	       err = UpdatePortObjectKpiData(StatMgr.NorthBoundPorts[PortStats.IntfID], PMData)
+	   } else {
+	       //PON ports
+	       err = UpdatePortObjectKpiData(SouthboundPorts[PortStats.IntfID], PMData)
+	   }
+	   if (err != nil) {
+	       log.Error("Error publishing statistics data")
+	   }
+	*/
+
+}
diff --git a/internal/pkg/core/statsmanager_test.go b/internal/pkg/core/statsmanager_test.go
new file mode 100644
index 0000000..6ea2487
--- /dev/null
+++ b/internal/pkg/core/statsmanager_test.go
@@ -0,0 +1,283 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package core
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-protos/v3/go/openolt"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+func init() {
+	_, _ = log.AddPackage(log.JSON, log.DebugLevel, nil)
+}
+func TestOpenOltStatisticsMgr_PortStatisticsIndication(t *testing.T) {
+	device := &voltha.Device{
+		Id:       "olt",
+		Root:     true,
+		ParentId: "logical_device",
+		Ports: []*voltha.Port{
+			{PortNo: 1, Label: "pon", Type: voltha.Port_ETHERNET_UNI},
+			{PortNo: 2, Label: "nni", Type: voltha.Port_ETHERNET_NNI},
+		},
+		ProxyAddress: &voltha.Device_ProxyAddress{
+			DeviceId:       "olt",
+			DeviceType:     "onu",
+			ChannelId:      1,
+			ChannelGroupId: 1,
+		},
+		ConnectStatus: 1,
+	}
+	dh := newMockDeviceHandler()
+	dh.device = device
+	StatMgr := NewOpenOltStatsMgr(dh)
+
+	type args struct {
+		PortStats *openolt.PortStatistics
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		// TODO: Add test cases.
+		{"PortStatisticsIndication", args{PortStats: &openolt.PortStatistics{}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+
+			StatMgr.PortStatisticsIndication(tt.args.PortStats, 16)
+		})
+	}
+}
+
+func TestOpenOltStatisticsMgr_publishMetrics(t *testing.T) {
+	type fields struct {
+		Device         *DeviceHandler
+		NorthBoundPort map[uint32]*NniPort
+		SouthBoundPort map[uint32]*PonPort
+	}
+	type args struct {
+		portType string
+		val      map[string]float32
+		portnum  uint32
+		context  map[string]string
+	}
+	ctx := map[string]string{}
+	ctx["deviceID"] = "Test"
+	ponmap := map[uint32]*PonPort{}
+	ponmap[0] = &PonPort{
+		PONID:          0,
+		DeviceID:       "onu1",
+		IntfID:         0,
+		PortNum:        0,
+		PortID:         0,
+		Label:          "",
+		ONUs:           nil,
+		ONUsByID:       nil,
+		RxBytes:        0,
+		RxPackets:      0,
+		RxUcastPackets: 0,
+		RxMcastPackets: 0,
+		RxBcastPackets: 0,
+		RxErrorPackets: 0,
+		TxBytes:        0,
+		TxPackets:      0,
+		TxUcastPackets: 0,
+		TxMcastPackets: 0,
+		TxBcastPackets: 0,
+		TxErrorPackets: 0,
+		RxCrcErrors:    0,
+		BipErrors:      0,
+	}
+	nnimap := map[uint32]*NniPort{}
+	nnimap[0] = &NniPort{
+		PortNum:        0,
+		Name:           "olt1",
+		LogicalPort:    0,
+		IntfID:         0,
+		RxBytes:        0,
+		RxPackets:      0,
+		RxUcastPackets: 0,
+		RxMcastPackets: uint64(1111),
+		RxBcastPackets: 0,
+		RxErrorPackets: 0,
+		TxBytes:        0,
+		TxPackets:      0,
+		TxUcastPackets: 0,
+		TxMcastPackets: 0,
+		TxBcastPackets: 0,
+		TxErrorPackets: 0,
+		RxCrcErrors:    0,
+		BipErrors:      0,
+	}
+	pval := make(map[string]float32)
+	pval["rx_bytes"] = float32(111)
+	nval := make(map[string]float32)
+	nval["rx_bytes"] = float32(111)
+	dhandlerNNI := newMockDeviceHandler()
+	dhandlerNNI.portStats = &OpenOltStatisticsMgr{Device: nil, SouthBoundPort: nil, NorthBoundPort: nnimap}
+	dhandlerPON := newMockDeviceHandler()
+	dhandlerPON.portStats = &OpenOltStatisticsMgr{Device: nil, SouthBoundPort: ponmap, NorthBoundPort: nil}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		{
+			name: "PublishNNIMetrics-1",
+			fields: fields{
+				Device:         dhandlerNNI,
+				NorthBoundPort: nnimap,
+				SouthBoundPort: nil,
+			},
+			args: args{
+				portType: "NNIStats",
+				val:      nval,
+				portnum:  0,
+				context:  ctx,
+			},
+		},
+		{
+			name: "PublishPONMetrics-1",
+			fields: fields{
+				Device:         dhandlerPON,
+				NorthBoundPort: nil,
+				SouthBoundPort: ponmap,
+			},
+			args: args{
+				portType: "PONStats",
+				val:      pval,
+				portnum:  0,
+				context:  ctx,
+			},
+		},
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			StatMgr := &OpenOltStatisticsMgr{
+				Device:         tt.fields.Device,
+				NorthBoundPort: tt.fields.NorthBoundPort,
+				SouthBoundPort: tt.fields.SouthBoundPort,
+			}
+			StatMgr.publishMetrics(tt.args.portType, tt.args.val, tt.args.portnum, tt.args.context, "onu1")
+
+		})
+	}
+}
+
+func TestOpenOltStatisticsMgr_collectNNIMetrics(t *testing.T) {
+	type fields struct {
+		Device         *DeviceHandler
+		NorthBoundPort map[uint32]*NniPort
+		SouthBoundPort map[uint32]*PonPort
+	}
+	type args struct {
+		nniID uint32
+	}
+	dhandler := newMockDeviceHandler()
+	pmconfig := make(map[string]*voltha.PmConfig)
+	pmconfig["rx_bytes"] = &voltha.PmConfig{Name: "olt"}
+
+	var res map[string]float32
+	nnimap := map[uint32]*NniPort{}
+	nnimap[0] = &NniPort{Name: "olt"}
+	nnimap[1] = &NniPort{Name: "olt"}
+	dh := &DeviceHandler{portStats: &OpenOltStatisticsMgr{Device: dhandler, SouthBoundPort: nil, NorthBoundPort: nnimap}}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   map[string]float32
+	}{
+		{"CollectNNIMetrics-1", fields{
+			Device:         dh,
+			NorthBoundPort: nnimap,
+			SouthBoundPort: nil,
+		}, args{0}, res},
+		{"CollectNNIMetrics-2", fields{
+			Device:         dh,
+			NorthBoundPort: nnimap,
+			SouthBoundPort: nil,
+		}, args{1}, res},
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			StatMgr := &OpenOltStatisticsMgr{
+				Device:         tt.fields.Device,
+				NorthBoundPort: tt.fields.NorthBoundPort,
+				SouthBoundPort: tt.fields.SouthBoundPort,
+			}
+			got := StatMgr.collectNNIMetrics(tt.args.nniID)
+			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("collectNNIMetrics() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltStatisticsMgr_collectPONMetrics(t *testing.T) {
+	type fields struct {
+		Device         *DeviceHandler
+		NorthBoundPort map[uint32]*NniPort
+		SouthBoundPort map[uint32]*PonPort
+	}
+	type args struct {
+		pID uint32
+	}
+	dhandler := newMockDeviceHandler()
+	pmconfig := make(map[string]*voltha.PmConfig)
+	pmconfig["rx_bytes"] = &voltha.PmConfig{Name: "olt"}
+
+	var res map[string]float32
+	ponmap := map[uint32]*PonPort{}
+	ponmap[0] = &PonPort{DeviceID: "olt"}
+	ponmap[1] = &PonPort{DeviceID: "olt"}
+	dh := &DeviceHandler{portStats: &OpenOltStatisticsMgr{Device: dhandler, SouthBoundPort: ponmap, NorthBoundPort: nil}}
+
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   map[string]float32
+	}{
+		{"CollectPONMetrics-1", fields{
+			Device:         dh,
+			NorthBoundPort: nil,
+			SouthBoundPort: ponmap,
+		}, args{0}, res},
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			StatMgr := &OpenOltStatisticsMgr{
+				Device:         tt.fields.Device,
+				NorthBoundPort: tt.fields.NorthBoundPort,
+				SouthBoundPort: tt.fields.SouthBoundPort,
+			}
+			got := StatMgr.collectPONMetrics(tt.args.pID)
+			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("collectPONMetrics() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/resourcemanager/resourcemanager.go b/internal/pkg/resourcemanager/resourcemanager.go
new file mode 100755
index 0000000..7dcdbb3
--- /dev/null
+++ b/internal/pkg/resourcemanager/resourcemanager.go
@@ -0,0 +1,1455 @@
+/*
+ * 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 resourcemanager provides the utility for managing resources
+package resourcemanager
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/db"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ponrmgr "github.com/opencord/voltha-lib-go/v3/pkg/ponresourcemanager"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/openolt"
+)
+
+const (
+	// KvstoreTimeout specifies the time out for KV Store Connection
+	KvstoreTimeout = 5
+	// BasePathKvStore - service/voltha/openolt/<device_id>
+	BasePathKvStore = "service/voltha/openolt/{%s}"
+	// TpIDPathSuffix - <(pon_id, onu_id, uni_id)>/tp_id
+	TpIDPathSuffix = "{%d,%d,%d}/tp_id"
+	//MeterIDPathSuffix - <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+	MeterIDPathSuffix = "{%d,%d,%d}/{%d}/meter_id/{%s}"
+	//NnniIntfID - nniintfids
+	NnniIntfID = "nniintfids"
+	// OnuPacketINPath path on the kvstore to store packetin gemport,which will be used for packetin, pcketout
+	//format: onu_packetin/<intfid>,<onuid>,<logicalport>
+	OnuPacketINPath = "onu_packetin/{%d,%d,%d}"
+	//FlowIDsForGem flowids_per_gem/<intfid>
+	FlowIDsForGem = "flowids_per_gem/{%d}"
+	//McastQueuesForIntf multicast queues for pon interfaces
+	McastQueuesForIntf = "mcast_qs_for_int"
+	//FlowGroup flow_groups/<flow_group_id>
+	// A group is stored under this path on the KV store after it has been installed to the device.
+	// It should also be deleted after it has been removed from the device accordingly.
+	FlowGroup = "flow_groups/{%d}"
+	//FlowGroupCached flow_groups_cached/<flow_group_id>
+	// When a group add request received, we create the group without setting any members to it since we cannot
+	// set any members to a group until it is associated with a multicast flow. It is a BAL limitation.
+	// When the related multicast flow has been created we perform set members operation for the group.
+	// That is why we need to keep the members of a group until the multicast flow creation request comes.
+	// We preserve the groups under "FlowGroupsCached" directory in the KV store temporarily. Having set members,
+	// we remove the group from the cached group store.
+	FlowGroupCached = "flow_groups_cached/{%d}"
+)
+
+// FlowInfo holds the flow information
+type FlowInfo struct {
+	Flow            *openolt.Flow
+	FlowStoreCookie uint64
+	FlowCategory    string
+	LogicalFlowID   uint64
+}
+
+// OnuGemInfo holds onu information along with gem port list and uni port list
+type OnuGemInfo struct {
+	OnuID        uint32
+	SerialNumber string
+	IntfID       uint32
+	GemPorts     []uint32
+	UniPorts     []uint32
+}
+
+// PacketInInfoKey is the key for packet in gemport
+type PacketInInfoKey struct {
+	IntfID      uint32
+	OnuID       uint32
+	LogicalPort uint32
+}
+
+// GroupInfo holds group information
+type GroupInfo struct {
+	GroupID  uint32
+	OutPorts []uint32
+}
+
+// OpenOltResourceMgr holds resource related information as provided below for each field
+type OpenOltResourceMgr struct {
+	DeviceID    string      // OLT device id
+	HostAndPort string      // Host and port of the kv store to connect to
+	Args        string      // args
+	KVStore     *db.Backend // backend kv store connection handle
+	DeviceType  string
+	Host        string              // Host ip of the kv store
+	Port        int                 // port of the kv store
+	DevInfo     *openolt.DeviceInfo // device information
+	// array of pon resource managers per interface technology
+	ResourceMgrs map[uint32]*ponrmgr.PONResourceManager
+}
+
+func newKVClient(storeType string, address string, timeout uint32) (kvstore.Client, error) {
+	log.Infow("kv-store-type", log.Fields{"store": storeType})
+	switch storeType {
+	case "consul":
+		return kvstore.NewConsulClient(address, int(timeout))
+	case "etcd":
+		return kvstore.NewEtcdClient(address, int(timeout))
+	}
+	return nil, errors.New("unsupported-kv-store")
+}
+
+// SetKVClient sets the KV client and return a kv backend
+func SetKVClient(backend string, Host string, Port int, DeviceID string) *db.Backend {
+	addr := Host + ":" + strconv.Itoa(Port)
+	// TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
+	// issue between kv store and backend , core is not calling NewBackend directly
+	kvClient, err := newKVClient(backend, addr, KvstoreTimeout)
+	if err != nil {
+		log.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
+		return nil
+	}
+	kvbackend := &db.Backend{
+		Client:     kvClient,
+		StoreType:  backend,
+		Host:       Host,
+		Port:       Port,
+		Timeout:    KvstoreTimeout,
+		PathPrefix: fmt.Sprintf(BasePathKvStore, DeviceID)}
+
+	return kvbackend
+}
+
+// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
+// instances according to technology. Initializes the default resource ranges for all
+// the resources.
+func NewResourceMgr(ctx context.Context, deviceID string, KVStoreHostPort string, kvStoreType string, deviceType string, devInfo *openolt.DeviceInfo) *OpenOltResourceMgr {
+	var ResourceMgr OpenOltResourceMgr
+	log.Debugf("Init new resource manager , host_port: %s, deviceid: %s", KVStoreHostPort, deviceID)
+	ResourceMgr.HostAndPort = KVStoreHostPort
+	ResourceMgr.DeviceType = deviceType
+	ResourceMgr.DevInfo = devInfo
+	IPPort := strings.Split(KVStoreHostPort, ":")
+	ResourceMgr.Host = IPPort[0]
+	ResourceMgr.Port, _ = strconv.Atoi(IPPort[1])
+
+	Backend := kvStoreType
+	ResourceMgr.KVStore = SetKVClient(Backend, ResourceMgr.Host,
+		ResourceMgr.Port, deviceID)
+	if ResourceMgr.KVStore == nil {
+		log.Error("Failed to setup KV store")
+	}
+	Ranges := make(map[string]*openolt.DeviceInfo_DeviceResourceRanges)
+	RsrcMgrsByTech := make(map[string]*ponrmgr.PONResourceManager)
+	ResourceMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager)
+
+	// TODO self.args = registry('main').get_args()
+
+	/*
+	   If a legacy driver returns protobuf without any ranges,s synthesize one from
+	   the legacy global per-device information. This, in theory, is temporary until
+	   the legacy drivers are upgrade to support pool ranges.
+	*/
+	if devInfo.Ranges == nil {
+		var ranges openolt.DeviceInfo_DeviceResourceRanges
+		ranges.Technology = devInfo.GetTechnology()
+
+		NumPONPorts := devInfo.GetPonPorts()
+		var index uint32
+		for index = 0; index < NumPONPorts; index++ {
+			ranges.IntfIds = append(ranges.IntfIds, index)
+		}
+
+		var Pool openolt.DeviceInfo_DeviceResourceRanges_Pool
+		Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID
+		Pool.Start = devInfo.OnuIdStart
+		Pool.End = devInfo.OnuIdEnd
+		Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
+		onuPool := Pool
+		ranges.Pools = append(ranges.Pools, &onuPool)
+
+		Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID
+		Pool.Start = devInfo.AllocIdStart
+		Pool.End = devInfo.AllocIdEnd
+		Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
+		allocPool := Pool
+		ranges.Pools = append(ranges.Pools, &allocPool)
+
+		Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID
+		Pool.Start = devInfo.GemportIdStart
+		Pool.End = devInfo.GemportIdEnd
+		Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
+		gemPool := Pool
+		ranges.Pools = append(ranges.Pools, &gemPool)
+
+		Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID
+		Pool.Start = devInfo.FlowIdStart
+		Pool.End = devInfo.FlowIdEnd
+		Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
+		ranges.Pools = append(ranges.Pools, &Pool)
+		// Add to device info
+		devInfo.Ranges = append(devInfo.Ranges, &ranges)
+	}
+
+	// Create a separate Resource Manager instance for each range. This assumes that
+	// each technology is represented by only a single range
+	var GlobalPONRsrcMgr *ponrmgr.PONResourceManager
+	var err error
+	for _, TechRange := range devInfo.Ranges {
+		technology := TechRange.Technology
+		log.Debugf("Device info technology %s", technology)
+		Ranges[technology] = TechRange
+		RsrcMgrsByTech[technology], err = ponrmgr.NewPONResourceManager(technology, deviceType, deviceID,
+			Backend, ResourceMgr.Host, ResourceMgr.Port)
+		if err != nil {
+			log.Errorf("Failed to create pon resource manager instance for technology %s", technology)
+			return nil
+		}
+		// resource_mgrs_by_tech[technology] = resource_mgr
+		if GlobalPONRsrcMgr == nil {
+			GlobalPONRsrcMgr = RsrcMgrsByTech[technology]
+		}
+		for _, IntfID := range TechRange.IntfIds {
+			ResourceMgr.ResourceMgrs[uint32(IntfID)] = RsrcMgrsByTech[technology]
+		}
+		// self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
+		InitializeDeviceResourceRangeAndPool(ctx, RsrcMgrsByTech[technology], GlobalPONRsrcMgr,
+			TechRange, devInfo)
+	}
+	// After we have initialized resource ranges, initialize the
+	// resource pools accordingly.
+	for _, PONRMgr := range RsrcMgrsByTech {
+		_ = PONRMgr.InitDeviceResourcePool(ctx)
+	}
+	log.Info("Initialization of  resource manager success!")
+	return &ResourceMgr
+}
+
+// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
+// device specific information. If KV doesn't exist
+// or is broader than the device, the device's information will
+// dictate the range limits
+func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager, globalPONRMgr *ponrmgr.PONResourceManager,
+	techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
+
+	// init the resource range pool according to the sharing type
+
+	log.Debugf("Resource range pool init for technology %s", ponRMgr.Technology)
+	// first load from KV profiles
+	status := ponRMgr.InitResourceRangesFromKVStore(ctx)
+	if !status {
+		log.Debugf("Failed to load resource ranges from KV store for tech %s", ponRMgr.Technology)
+	}
+
+	/*
+	   Then apply device specific information. If KV doesn't exist
+	   or is broader than the device, the device's information will
+	   dictate the range limits
+	*/
+	log.Debugw("Using device info to init pon resource ranges", log.Fields{"Tech": ponRMgr.Technology})
+
+	ONUIDStart := devInfo.OnuIdStart
+	ONUIDEnd := devInfo.OnuIdEnd
+	ONUIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
+	ONUIDSharedPoolID := uint32(0)
+	AllocIDStart := devInfo.AllocIdStart
+	AllocIDEnd := devInfo.AllocIdEnd
+	AllocIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
+	AllocIDSharedPoolID := uint32(0)
+	GEMPortIDStart := devInfo.GemportIdStart
+	GEMPortIDEnd := devInfo.GemportIdEnd
+	GEMPortIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
+	GEMPortIDSharedPoolID := uint32(0)
+	FlowIDStart := devInfo.FlowIdStart
+	FlowIDEnd := devInfo.FlowIdEnd
+	FlowIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
+	FlowIDSharedPoolID := uint32(0)
+
+	var FirstIntfPoolID uint32
+	var SharedPoolID uint32
+
+	/*
+	 * As a zero check is made against SharedPoolID to check whether the resources are shared across all intfs
+	 * if resources are shared across interfaces then SharedPoolID is given a positive number.
+	 */
+	for _, FirstIntfPoolID = range techRange.IntfIds {
+		// skip the intf id 0
+		if FirstIntfPoolID == 0 {
+			continue
+		}
+		break
+	}
+
+	for _, RangePool := range techRange.Pools {
+		if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
+			SharedPoolID = FirstIntfPoolID
+		} else if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_SAME_TECH {
+			SharedPoolID = FirstIntfPoolID
+		} else {
+			SharedPoolID = 0
+		}
+		if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
+			ONUIDStart = RangePool.Start
+			ONUIDEnd = RangePool.End
+			ONUIDShared = RangePool.Sharing
+			ONUIDSharedPoolID = SharedPoolID
+		} else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
+			AllocIDStart = RangePool.Start
+			AllocIDEnd = RangePool.End
+			AllocIDShared = RangePool.Sharing
+			AllocIDSharedPoolID = SharedPoolID
+		} else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
+			GEMPortIDStart = RangePool.Start
+			GEMPortIDEnd = RangePool.End
+			GEMPortIDShared = RangePool.Sharing
+			GEMPortIDSharedPoolID = SharedPoolID
+		} else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID {
+			FlowIDStart = RangePool.Start
+			FlowIDEnd = RangePool.End
+			FlowIDShared = RangePool.Sharing
+			FlowIDSharedPoolID = SharedPoolID
+		}
+	}
+
+	log.Debugw("Device info init", log.Fields{"technology": techRange.Technology,
+		"onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd, "onu_id_shared_pool_id": ONUIDSharedPoolID,
+		"alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
+		"alloc_id_shared_pool_id": AllocIDSharedPoolID,
+		"gemport_id_start":        GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
+		"gemport_id_shared_pool_id": GEMPortIDSharedPoolID,
+		"flow_id_start":             FlowIDStart,
+		"flow_id_end_idx":           FlowIDEnd,
+		"flow_id_shared_pool_id":    FlowIDSharedPoolID,
+		"intf_ids":                  techRange.IntfIds,
+		"uni_id_start":              0,
+		"uni_id_end_idx":            1, /*MaxUNIIDperONU()*/
+	})
+
+	ponRMgr.InitDefaultPONResourceRanges(ONUIDStart, ONUIDEnd, ONUIDSharedPoolID,
+		AllocIDStart, AllocIDEnd, AllocIDSharedPoolID,
+		GEMPortIDStart, GEMPortIDEnd, GEMPortIDSharedPoolID,
+		FlowIDStart, FlowIDEnd, FlowIDSharedPoolID, 0, 1,
+		devInfo.PonPorts, techRange.IntfIds)
+
+	// For global sharing, make sure to refresh both local and global resource manager instances' range
+
+	if ONUIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
+		globalPONRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd,
+			"", 0, nil)
+		ponRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd,
+			"", 0, globalPONRMgr)
+	}
+	if AllocIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
+		globalPONRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd,
+			"", 0, nil)
+
+		ponRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd,
+			"", 0, globalPONRMgr)
+	}
+	if GEMPortIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
+		globalPONRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd,
+			"", 0, nil)
+		ponRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd,
+			"", 0, globalPONRMgr)
+	}
+	if FlowIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
+		globalPONRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd,
+			"", 0, nil)
+		ponRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd,
+			"", 0, globalPONRMgr)
+	}
+
+	// Make sure loaded range fits the platform bit encoding ranges
+	ponRMgr.UpdateRanges(ponrmgr.UNI_ID_START_IDX, 0, ponrmgr.UNI_ID_END_IDX /* TODO =OpenOltPlatform.MAX_UNIS_PER_ONU-1*/, 1, "", 0, nil)
+}
+
+// Delete clears used resources for the particular olt device being deleted
+func (RsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context) error {
+	/* TODO
+	   def __del__(self):
+	           self.log.info("clearing-device-resource-pool")
+	           for key, resource_mgr in self.resource_mgrs.iteritems():
+	               resource_mgr.clear_device_resource_pool()
+
+	       def assert_pon_id_limit(self, pon_intf_id):
+	           assert pon_intf_id in self.resource_mgrs
+
+	       def assert_onu_id_limit(self, pon_intf_id, onu_id):
+	           self.assert_pon_id_limit(pon_intf_id)
+	           self.resource_mgrs[pon_intf_id].assert_resource_limits(onu_id, PONResourceManager.ONU_ID)
+
+	       @property
+	       def max_uni_id_per_onu(self):
+	           return 0 #OpenOltPlatform.MAX_UNIS_PER_ONU-1, zero-based indexing Uncomment or override to make default multi-uni
+
+	       def assert_uni_id_limit(self, pon_intf_id, onu_id, uni_id):
+	           self.assert_onu_id_limit(pon_intf_id, onu_id)
+	           self.resource_mgrs[pon_intf_id].assert_resource_limits(uni_id, PONResourceManager.UNI_ID)
+	*/
+	for _, rsrcMgr := range RsrcMgr.ResourceMgrs {
+		if err := rsrcMgr.ClearDeviceResourcePool(ctx); err != nil {
+			log.Debug("Failed to clear device resource pool")
+			return err
+		}
+	}
+	log.Debug("Cleared device resource pool")
+	return nil
+}
+
+// GetONUID returns the available OnuID for the given pon-port
+func (RsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context, ponIntfID uint32) (uint32, error) {
+	// Check if Pon Interface ID is present in Resource-manager-map
+	if _, ok := RsrcMgr.ResourceMgrs[ponIntfID]; !ok {
+		err := errors.New("invalid-pon-interface-" + strconv.Itoa(int(ponIntfID)))
+		return 0, err
+	}
+	// Get ONU id for a provided pon interface ID.
+	ONUID, err := RsrcMgr.ResourceMgrs[ponIntfID].GetResourceID(ctx, ponIntfID,
+		ponrmgr.ONU_ID, 1)
+	if err != nil {
+		log.Errorf("Failed to get resource for interface %d for type %s",
+			ponIntfID, ponrmgr.ONU_ID)
+		return 0, err
+	}
+	if ONUID != nil {
+		RsrcMgr.ResourceMgrs[ponIntfID].InitResourceMap(ctx, fmt.Sprintf("%d,%d", ponIntfID, ONUID[0]))
+		return ONUID[0], err
+	}
+
+	return 0, err // return OnuID 0 on error
+}
+
+// GetFlowIDInfo returns the slice of flow info of the given pon-port
+// Note: For flows which trap from the NNI and not really associated with any particular
+// ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
+func (RsrcMgr *OpenOltResourceMgr) GetFlowIDInfo(ctx context.Context, ponIntfID uint32, onuID int32, uniID int32, flowID uint32) *[]FlowInfo {
+	var flows []FlowInfo
+
+	FlowPath := fmt.Sprintf("%d,%d,%d", ponIntfID, onuID, uniID)
+	if err := RsrcMgr.ResourceMgrs[ponIntfID].GetFlowIDInfo(ctx, FlowPath, flowID, &flows); err != nil {
+		log.Errorw("Error while getting flows from KV store", log.Fields{"flowId": flowID})
+		return nil
+	}
+	if len(flows) == 0 {
+		log.Debugw("No flowInfo found in KV store", log.Fields{"flowPath": FlowPath})
+		return nil
+	}
+	return &flows
+}
+
+// GetCurrentFlowIDsForOnu fetches flow ID from the resource manager
+// Note: For flows which trap from the NNI and not really associated with any particular
+// ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
+func (RsrcMgr *OpenOltResourceMgr) GetCurrentFlowIDsForOnu(ctx context.Context, PONIntfID uint32, ONUID int32, UNIID int32) []uint32 {
+
+	FlowPath := fmt.Sprintf("%d,%d,%d", PONIntfID, ONUID, UNIID)
+	if mgrs, exist := RsrcMgr.ResourceMgrs[PONIntfID]; exist {
+		return mgrs.GetCurrentFlowIDsForOnu(ctx, FlowPath)
+	}
+	return nil
+}
+
+// UpdateFlowIDInfo updates flow info for the given pon interface, onu id, and uni id
+// Note: For flows which trap from the NNI and not really associated with any particular
+// ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
+func (RsrcMgr *OpenOltResourceMgr) UpdateFlowIDInfo(ctx context.Context, ponIntfID int32, onuID int32, uniID int32,
+	flowID uint32, flowData *[]FlowInfo) error {
+	FlowPath := fmt.Sprintf("%d,%d,%d", ponIntfID, onuID, uniID)
+	return RsrcMgr.ResourceMgrs[uint32(ponIntfID)].UpdateFlowIDInfoForOnu(ctx, FlowPath, flowID, *flowData)
+}
+
+// GetFlowID return flow ID for a given pon interface id, onu id and uni id
+func (RsrcMgr *OpenOltResourceMgr) GetFlowID(ctx context.Context, ponIntfID uint32, ONUID int32, uniID int32,
+	gemportID uint32,
+	flowStoreCookie uint64,
+	flowCategory string, vlanPcp ...uint32) (uint32, error) {
+
+	var err error
+	FlowPath := fmt.Sprintf("%d,%d,%d", ponIntfID, ONUID, uniID)
+	FlowIDs := RsrcMgr.ResourceMgrs[ponIntfID].GetCurrentFlowIDsForOnu(ctx, FlowPath)
+	if FlowIDs != nil {
+		log.Debugw("Found flowId(s) for this ONU", log.Fields{"pon": ponIntfID, "ONUID": ONUID, "uniID": uniID, "KVpath": FlowPath})
+		for _, flowID := range FlowIDs {
+			FlowInfo := RsrcMgr.GetFlowIDInfo(ctx, ponIntfID, int32(ONUID), int32(uniID), uint32(flowID))
+			er := getFlowIDFromFlowInfo(FlowInfo, flowID, gemportID, flowStoreCookie, flowCategory, vlanPcp...)
+			if er == nil {
+				return flowID, er
+			}
+		}
+	}
+	log.Debug("No matching flows with flow cookie or flow category, allocating new flowid")
+	FlowIDs, err = RsrcMgr.ResourceMgrs[ponIntfID].GetResourceID(ctx, ponIntfID,
+		ponrmgr.FLOW_ID, 1)
+	if err != nil {
+		log.Errorf("Failed to get resource for interface %d for type %s",
+			ponIntfID, ponrmgr.FLOW_ID)
+		return uint32(0), err
+	}
+	if FlowIDs != nil {
+		_ = RsrcMgr.ResourceMgrs[ponIntfID].UpdateFlowIDForOnu(ctx, FlowPath, FlowIDs[0], true)
+		return FlowIDs[0], err
+	}
+
+	return 0, err
+}
+
+// GetAllocID return the first Alloc ID for a given pon interface id and onu id and then update the resource map on
+// the KV store with the list of alloc_ids allocated for the pon_intf_onu_id tuple
+// Currently of all the alloc_ids available, it returns the first alloc_id in the list for tha given ONU
+func (RsrcMgr *OpenOltResourceMgr) GetAllocID(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) uint32 {
+
+	var err error
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
+	AllocID := RsrcMgr.ResourceMgrs[intfID].GetCurrentAllocIDForOnu(ctx, IntfOnuIDUniID)
+	if AllocID != nil {
+		// Since we support only one alloc_id for the ONU at the moment,
+		// return the first alloc_id in the list, if available, for that
+		// ONU.
+		log.Debugw("Retrieved alloc ID from pon resource mgr", log.Fields{"AllocID": AllocID})
+		return AllocID[0]
+	}
+	AllocID, err = RsrcMgr.ResourceMgrs[intfID].GetResourceID(ctx, intfID,
+		ponrmgr.ALLOC_ID, 1)
+
+	if AllocID == nil || err != nil {
+		log.Error("Failed to allocate alloc id")
+		return 0
+	}
+	// update the resource map on KV store with the list of alloc_id
+	// allocated for the pon_intf_onu_id tuple
+	err = RsrcMgr.ResourceMgrs[intfID].UpdateAllocIdsForOnu(ctx, IntfOnuIDUniID, AllocID)
+	if err != nil {
+		log.Error("Failed to update Alloc ID")
+		return 0
+	}
+	log.Debugw("Allocated new Tcont from pon resource mgr", log.Fields{"AllocID": AllocID})
+	return AllocID[0]
+}
+
+// UpdateAllocIdsForOnu updates alloc ids in kv store for a given pon interface id, onu id and uni id
+func (RsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, ponPort uint32, onuID uint32, uniID uint32, allocID []uint32) error {
+
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
+	return RsrcMgr.ResourceMgrs[ponPort].UpdateAllocIdsForOnu(ctx, IntfOnuIDUniID,
+		allocID)
+}
+
+// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
+func (RsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, intfID uint32, onuID uint32,
+	uniID uint32) []uint32 {
+
+	/* Get gem ports for given pon interface , onu id and uni id. */
+
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
+	return RsrcMgr.ResourceMgrs[intfID].GetCurrentGEMPortIDsForOnu(ctx, IntfOnuIDUniID)
+}
+
+// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
+func (RsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
+
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
+	AllocID := RsrcMgr.ResourceMgrs[intfID].GetCurrentAllocIDForOnu(ctx, IntfOnuIDUniID)
+	if AllocID != nil {
+		return AllocID
+	}
+	return []uint32{}
+}
+
+// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
+func (RsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32) {
+	allocIDs := RsrcMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
+	for i := 0; i < len(allocIDs); i++ {
+		if allocIDs[i] == allocID {
+			allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
+			break
+		}
+	}
+	err := RsrcMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocIDs)
+	if err != nil {
+		log.Errorf("Failed to Remove Alloc Id For Onu. IntfID %d onuID %d uniID %d allocID %d",
+			intfID, onuID, uniID, allocID)
+	}
+}
+
+// RemoveGemPortIDForOnu removes the gem port id for given pon interface, onu id, uni id and gem port id
+func (RsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32) {
+	gemPortIDs := RsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
+	for i := 0; i < len(gemPortIDs); i++ {
+		if gemPortIDs[i] == gemPortID {
+			gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
+			break
+		}
+	}
+	err := RsrcMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs)
+	if err != nil {
+		log.Errorf("Failed to Remove Gem Id For Onu. IntfID %d onuID %d uniID %d gemPortId %d",
+			intfID, onuID, uniID, gemPortID)
+	}
+}
+
+// UpdateGEMportsPonportToOnuMapOnKVStore updates onu and uni id associated with the gem port to the kv store
+// This stored information is used when packet_indication is received and we need to derive the ONU Id for which
+// the packet arrived based on the pon_intf and gemport available in the packet_indication
+func (RsrcMgr *OpenOltResourceMgr) UpdateGEMportsPonportToOnuMapOnKVStore(ctx context.Context, gemPorts []uint32, PonPort uint32,
+	onuID uint32, uniID uint32) error {
+
+	/* Update onu and uni id associated with the gem port to the kv store. */
+	var IntfGEMPortPath string
+	Data := fmt.Sprintf("%d %d", onuID, uniID)
+	for _, GEM := range gemPorts {
+		IntfGEMPortPath = fmt.Sprintf("%d,%d", PonPort, GEM)
+		Val, err := json.Marshal(Data)
+		if err != nil {
+			log.Error("failed to Marshal")
+			return err
+		}
+
+		if err = RsrcMgr.KVStore.Put(ctx, IntfGEMPortPath, Val); err != nil {
+			log.Errorf("Failed to update resource %s", IntfGEMPortPath)
+			return err
+		}
+	}
+	return nil
+}
+
+// RemoveGEMportPonportToOnuMapOnKVStore removes the relationship between the gem port and pon port
+func (RsrcMgr *OpenOltResourceMgr) RemoveGEMportPonportToOnuMapOnKVStore(ctx context.Context, GemPort uint32, PonPort uint32) {
+	IntfGEMPortPath := fmt.Sprintf("%d,%d", PonPort, GemPort)
+	err := RsrcMgr.KVStore.Delete(ctx, IntfGEMPortPath)
+	if err != nil {
+		log.Errorf("Failed to Remove Gem port-Pon port to onu map on kv store. Gem %d PonPort %d", GemPort, PonPort)
+	}
+}
+
+// GetGEMPortID gets gem port id for a particular pon port, onu id and uni id and then update the resource map on
+// the KV store with the list of gemport_id allocated for the pon_intf_onu_id tuple
+func (RsrcMgr *OpenOltResourceMgr) GetGEMPortID(ctx context.Context, ponPort uint32, onuID uint32,
+	uniID uint32, NumOfPorts uint32) ([]uint32, error) {
+
+	/* Get gem port id for a particular pon port, onu id
+	   and uni id.
+	*/
+
+	var err error
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
+
+	GEMPortList := RsrcMgr.ResourceMgrs[ponPort].GetCurrentGEMPortIDsForOnu(ctx, IntfOnuIDUniID)
+	if GEMPortList != nil {
+		return GEMPortList, nil
+	}
+
+	GEMPortList, err = RsrcMgr.ResourceMgrs[ponPort].GetResourceID(ctx, ponPort,
+		ponrmgr.GEMPORT_ID, NumOfPorts)
+	if err != nil && GEMPortList == nil {
+		log.Errorf("Failed to get gem port id for %s", IntfOnuIDUniID)
+		return nil, err
+	}
+
+	// update the resource map on KV store with the list of gemport_id
+	// allocated for the pon_intf_onu_id tuple
+	err = RsrcMgr.ResourceMgrs[ponPort].UpdateGEMPortIDsForOnu(ctx, IntfOnuIDUniID,
+		GEMPortList)
+	if err != nil {
+		log.Errorf("Failed to update GEM ports to kv store for %s", IntfOnuIDUniID)
+		return nil, err
+	}
+	_ = RsrcMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, GEMPortList, ponPort,
+		onuID, uniID)
+	return GEMPortList, err
+}
+
+// UpdateGEMPortIDsForOnu updates gemport ids on to the kv store for a given pon port, onu id and uni id
+func (RsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, ponPort uint32, onuID uint32,
+	uniID uint32, GEMPortList []uint32) error {
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
+	return RsrcMgr.ResourceMgrs[ponPort].UpdateGEMPortIDsForOnu(ctx, IntfOnuIDUniID,
+		GEMPortList)
+
+}
+
+// FreeonuID releases(make free) onu id for a particular pon-port
+func (RsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, intfID uint32, onuID []uint32) {
+
+	RsrcMgr.ResourceMgrs[intfID].FreeResourceID(ctx, intfID, ponrmgr.ONU_ID, onuID)
+
+	/* Free onu id for a particular interface.*/
+	var IntfonuID string
+	for _, onu := range onuID {
+		IntfonuID = fmt.Sprintf("%d,%d", intfID, onu)
+		RsrcMgr.ResourceMgrs[intfID].RemoveResourceMap(ctx, IntfonuID)
+	}
+}
+
+// FreeFlowID returns the free flow id for a given interface, onu id and uni id
+func (RsrcMgr *OpenOltResourceMgr) FreeFlowID(ctx context.Context, IntfID uint32, onuID int32,
+	uniID int32, FlowID uint32) {
+	var IntfONUID string
+	var err error
+	FlowIds := make([]uint32, 0)
+
+	FlowIds = append(FlowIds, FlowID)
+	IntfONUID = fmt.Sprintf("%d,%d,%d", IntfID, onuID, uniID)
+	err = RsrcMgr.ResourceMgrs[IntfID].UpdateFlowIDForOnu(ctx, IntfONUID, FlowID, false)
+	if err != nil {
+		log.Errorw("Failed to Update flow id  for", log.Fields{"intf": IntfONUID})
+	}
+	RsrcMgr.ResourceMgrs[IntfID].RemoveFlowIDInfo(ctx, IntfONUID, FlowID)
+	RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(ctx, IntfID, ponrmgr.FLOW_ID, FlowIds)
+}
+
+// FreeFlowIDs releases the flow Ids
+func (RsrcMgr *OpenOltResourceMgr) FreeFlowIDs(ctx context.Context, IntfID uint32, onuID uint32,
+	uniID uint32, FlowID []uint32) {
+
+	RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(ctx, IntfID, ponrmgr.FLOW_ID, FlowID)
+
+	var IntfOnuIDUniID string
+	var err error
+	for _, flow := range FlowID {
+		IntfOnuIDUniID = fmt.Sprintf("%d,%d,%d", IntfID, onuID, uniID)
+		err = RsrcMgr.ResourceMgrs[IntfID].UpdateFlowIDForOnu(ctx, IntfOnuIDUniID, flow, false)
+		if err != nil {
+			log.Errorw("Failed to Update flow id for", log.Fields{"intf": IntfOnuIDUniID})
+		}
+		RsrcMgr.ResourceMgrs[IntfID].RemoveFlowIDInfo(ctx, IntfOnuIDUniID, flow)
+	}
+}
+
+// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
+// for the given OLT device.
+func (RsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, IntfID uint32, onuID uint32,
+	uniID uint32, allocID uint32) {
+	RsrcMgr.RemoveAllocIDForOnu(ctx, IntfID, onuID, uniID, allocID)
+	allocIDs := make([]uint32, 0)
+	allocIDs = append(allocIDs, allocID)
+	RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(ctx, IntfID, ponrmgr.ALLOC_ID, allocIDs)
+}
+
+// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
+// for the given OLT device.
+func (RsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, IntfID uint32, onuID uint32,
+	uniID uint32, gemPortID uint32) {
+	RsrcMgr.RemoveGemPortIDForOnu(ctx, IntfID, onuID, uniID, gemPortID)
+	gemPortIDs := make([]uint32, 0)
+	gemPortIDs = append(gemPortIDs, gemPortID)
+	RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(ctx, IntfID, ponrmgr.GEMPORT_ID, gemPortIDs)
+}
+
+// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id, and the clears the
+// resource map and the onuID associated with (pon_intf_id, gemport_id) tuple,
+func (RsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) {
+
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
+
+	AllocIDs := RsrcMgr.ResourceMgrs[intfID].GetCurrentAllocIDForOnu(ctx, IntfOnuIDUniID)
+
+	RsrcMgr.ResourceMgrs[intfID].FreeResourceID(ctx, intfID,
+		ponrmgr.ALLOC_ID,
+		AllocIDs)
+
+	GEMPortIDs := RsrcMgr.ResourceMgrs[intfID].GetCurrentGEMPortIDsForOnu(ctx, IntfOnuIDUniID)
+	RsrcMgr.ResourceMgrs[intfID].FreeResourceID(ctx, intfID,
+		ponrmgr.GEMPORT_ID,
+		GEMPortIDs)
+
+	FlowIDs := RsrcMgr.ResourceMgrs[intfID].GetCurrentFlowIDsForOnu(ctx, IntfOnuIDUniID)
+	RsrcMgr.ResourceMgrs[intfID].FreeResourceID(ctx, intfID,
+		ponrmgr.FLOW_ID,
+		FlowIDs)
+	// Clear resource map associated with (pon_intf_id, gemport_id) tuple.
+	RsrcMgr.ResourceMgrs[intfID].RemoveResourceMap(ctx, IntfOnuIDUniID)
+	// Clear the ONU Id associated with the (pon_intf_id, gemport_id) tuple.
+	for _, GEM := range GEMPortIDs {
+		_ = RsrcMgr.KVStore.Delete(ctx, fmt.Sprintf("%d,%d", intfID, GEM))
+	}
+}
+
+// IsFlowCookieOnKVStore checks if the given flow cookie is present on the kv store
+// Returns true if the flow cookie is found, otherwise it returns false
+func (RsrcMgr *OpenOltResourceMgr) IsFlowCookieOnKVStore(ctx context.Context, ponIntfID uint32, onuID int32, uniID int32,
+	flowStoreCookie uint64) bool {
+
+	FlowPath := fmt.Sprintf("%d,%d,%d", ponIntfID, onuID, uniID)
+	FlowIDs := RsrcMgr.ResourceMgrs[ponIntfID].GetCurrentFlowIDsForOnu(ctx, FlowPath)
+	if FlowIDs != nil {
+		log.Debugw("Found flowId(s) for this ONU", log.Fields{"pon": ponIntfID, "onuID": onuID, "uniID": uniID, "KVpath": FlowPath})
+		for _, flowID := range FlowIDs {
+			FlowInfo := RsrcMgr.GetFlowIDInfo(ctx, ponIntfID, int32(onuID), int32(uniID), uint32(flowID))
+			if FlowInfo != nil {
+				log.Debugw("Found flows", log.Fields{"flows": *FlowInfo, "flowId": flowID})
+				for _, Info := range *FlowInfo {
+					if Info.FlowStoreCookie == flowStoreCookie {
+						log.Debug("Found flow matching with flowStore cookie", log.Fields{"flowId": flowID, "flowStoreCookie": flowStoreCookie})
+						return true
+					}
+				}
+			}
+		}
+	}
+	return false
+}
+
+// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, IntfID uint32, OnuID uint32, UniID uint32) []uint32 {
+	Path := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
+	var Data []uint32
+	Value, err := RsrcMgr.KVStore.Get(ctx, Path)
+	if err == nil {
+		if Value != nil {
+			Val, err := kvstore.ToByte(Value.Value)
+			if err != nil {
+				log.Errorw("Failed to convert into byte array", log.Fields{"error": err})
+				return Data
+			}
+			if err = json.Unmarshal(Val, &Data); err != nil {
+				log.Error("Failed to unmarshal", log.Fields{"error": err})
+				return Data
+			}
+		}
+	} else {
+		log.Errorf("Failed to get TP id from kvstore for path %s", Path)
+	}
+	log.Debugf("Getting TP id %d from path %s", Data, Path)
+	return Data
+
+}
+
+// RemoveTechProfileIDsForOnu deletes all tech profile ids from the KV-Store for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, IntfID uint32, OnuID uint32, UniID uint32) error {
+	IntfOnuUniID := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
+	if err := RsrcMgr.KVStore.Delete(ctx, IntfOnuUniID); err != nil {
+		log.Errorw("Failed to delete techprofile id resource in KV store", log.Fields{"path": IntfOnuUniID})
+		return err
+	}
+	return nil
+}
+
+// RemoveTechProfileIDForOnu deletes a specific tech profile id from the KV-Store for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, IntfID uint32, OnuID uint32, UniID uint32, TpID uint32) error {
+	tpIDList := RsrcMgr.GetTechProfileIDForOnu(ctx, IntfID, OnuID, UniID)
+	for i, tpIDInList := range tpIDList {
+		if tpIDInList == TpID {
+			tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
+		}
+	}
+	IntfOnuUniID := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
+	Value, err := json.Marshal(tpIDList)
+	if err != nil {
+		log.Error("failed to Marshal")
+		return err
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, IntfOnuUniID, Value); err != nil {
+		log.Errorf("Failed to update resource %s", IntfOnuUniID)
+		return err
+	}
+	return err
+}
+
+// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, IntfID uint32, OnuID uint32,
+	UniID uint32, TpID uint32) error {
+	var Value []byte
+	var err error
+
+	IntfOnuUniID := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
+
+	tpIDList := RsrcMgr.GetTechProfileIDForOnu(ctx, IntfID, OnuID, UniID)
+	for _, value := range tpIDList {
+		if value == TpID {
+			log.Debugf("TpID %d is already in tpIdList for the path %s", TpID, IntfOnuUniID)
+			return err
+		}
+	}
+	log.Debugf("updating tp id %d on path %s", TpID, IntfOnuUniID)
+	tpIDList = append(tpIDList, TpID)
+	Value, err = json.Marshal(tpIDList)
+	if err != nil {
+		log.Error("failed to Marshal")
+		return err
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, IntfOnuUniID, Value); err != nil {
+		log.Errorf("Failed to update resource %s", IntfOnuUniID)
+		return err
+	}
+	return err
+}
+
+// UpdateMeterIDForOnu updates the meter id in the KV-Store for the given onu based on the path
+// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+func (RsrcMgr *OpenOltResourceMgr) UpdateMeterIDForOnu(ctx context.Context, Direction string, IntfID uint32, OnuID uint32,
+	UniID uint32, TpID uint32, MeterConfig *ofp.OfpMeterConfig) error {
+	var Value []byte
+	var err error
+
+	IntfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, TpID, Direction)
+	Value, err = json.Marshal(*MeterConfig)
+	if err != nil {
+		log.Error("failed to Marshal meter config")
+		return err
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, IntfOnuUniID, Value); err != nil {
+		log.Errorf("Failed to store meter into KV store %s", IntfOnuUniID)
+		return err
+	}
+	return err
+}
+
+// GetMeterIDForOnu fetches the meter id from the kv store for the given onu based on the path
+// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+func (RsrcMgr *OpenOltResourceMgr) GetMeterIDForOnu(ctx context.Context, Direction string, IntfID uint32, OnuID uint32,
+	UniID uint32, TpID uint32) (*ofp.OfpMeterConfig, error) {
+	Path := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, TpID, Direction)
+	var meterConfig ofp.OfpMeterConfig
+	Value, err := RsrcMgr.KVStore.Get(ctx, Path)
+	if err == nil {
+		if Value != nil {
+			log.Debug("Found meter in KV store", log.Fields{"Direction": Direction})
+			Val, er := kvstore.ToByte(Value.Value)
+			if er != nil {
+				log.Errorw("Failed to convert into byte array", log.Fields{"error": er})
+				return nil, er
+			}
+			if er = json.Unmarshal(Val, &meterConfig); er != nil {
+				log.Error("Failed to unmarshal meterconfig", log.Fields{"error": er})
+				return nil, er
+			}
+		} else {
+			log.Debug("meter-does-not-exists-in-KVStore")
+			return nil, err
+		}
+	} else {
+		log.Errorf("Failed to get Meter config from kvstore for path %s", Path)
+
+	}
+	return &meterConfig, err
+}
+
+// RemoveMeterIDForOnu deletes the meter id from the kV-Store for the given onu based on the path
+// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+func (RsrcMgr *OpenOltResourceMgr) RemoveMeterIDForOnu(ctx context.Context, Direction string, IntfID uint32, OnuID uint32,
+	UniID uint32, TpID uint32) error {
+	Path := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, TpID, Direction)
+	if err := RsrcMgr.KVStore.Delete(ctx, Path); err != nil {
+		log.Errorf("Failed to delete meter id %s from kvstore ", Path)
+		return err
+	}
+	return nil
+}
+
+func getFlowIDFromFlowInfo(FlowInfo *[]FlowInfo, flowID, gemportID uint32, flowStoreCookie uint64, flowCategory string, vlanPcp ...uint32) error {
+	if FlowInfo != nil {
+		for _, Info := range *FlowInfo {
+			if int32(gemportID) == Info.Flow.GemportId && flowCategory != "" && Info.FlowCategory == flowCategory {
+				log.Debug("Found flow matching with flow category", log.Fields{"flowId": flowID, "FlowCategory": flowCategory})
+				if Info.FlowCategory == "HSIA_FLOW" && Info.Flow.Classifier.OPbits == vlanPcp[0] {
+					log.Debug("Found matching vlan pcp ", log.Fields{"flowId": flowID, "Vlanpcp": vlanPcp[0]})
+					return nil
+				}
+			}
+			if int32(gemportID) == Info.Flow.GemportId && flowStoreCookie != 0 && Info.FlowStoreCookie == flowStoreCookie {
+				if flowCategory != "" && Info.FlowCategory == flowCategory {
+					log.Debug("Found flow matching with flow category", log.Fields{"flowId": flowID, "FlowCategory": flowCategory})
+					return nil
+				}
+			}
+		}
+	}
+	log.Debugw("the flow can be related to a different service", log.Fields{"flow_info": FlowInfo})
+	return errors.New("invalid flow-info")
+}
+
+//AddGemToOnuGemInfo adds gemport to onugem info kvstore
+func (RsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
+	var onuGemData []OnuGemInfo
+	var err error
+
+	if err = RsrcMgr.ResourceMgrs[intfID].GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
+		log.Errorf("failed to get onuifo for intfid %d", intfID)
+		return err
+	}
+	if len(onuGemData) == 0 {
+		log.Errorw("failed to ger Onuid info ", log.Fields{"intfid": intfID, "onuid": onuID})
+		return err
+	}
+
+	for idx, onugem := range onuGemData {
+		if onugem.OnuID == onuID {
+			for _, gem := range onuGemData[idx].GemPorts {
+				if gem == gemPort {
+					log.Debugw("Gem already present in onugem info, skpping addition", log.Fields{"gem": gem})
+					return nil
+				}
+			}
+			log.Debugw("Added gem to onugem info", log.Fields{"gem": gemPort})
+			onuGemData[idx].GemPorts = append(onuGemData[idx].GemPorts, gemPort)
+			break
+		}
+	}
+	err = RsrcMgr.ResourceMgrs[intfID].AddOnuGemInfo(ctx, intfID, onuGemData)
+	if err != nil {
+		log.Error("Failed to add onugem to kv store")
+		return err
+	}
+	return err
+}
+
+//GetOnuGemInfo gets onu gem info from the kvstore per interface
+func (RsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, IntfID uint32) ([]OnuGemInfo, error) {
+	var onuGemData []OnuGemInfo
+
+	if err := RsrcMgr.ResourceMgrs[IntfID].GetOnuGemInfo(ctx, IntfID, &onuGemData); err != nil {
+		log.Errorf("failed to get onuifo for intfid %d", IntfID)
+		return nil, err
+	}
+
+	return onuGemData, nil
+}
+
+// AddOnuGemInfo adds onu info on to the kvstore per interface
+func (RsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, IntfID uint32, onuGem OnuGemInfo) error {
+	var onuGemData []OnuGemInfo
+	var err error
+
+	if err = RsrcMgr.ResourceMgrs[IntfID].GetOnuGemInfo(ctx, IntfID, &onuGemData); err != nil {
+		log.Errorf("failed to get onuifo for intfid %d", IntfID)
+		return err
+	}
+	onuGemData = append(onuGemData, onuGem)
+	err = RsrcMgr.ResourceMgrs[IntfID].AddOnuGemInfo(ctx, IntfID, onuGemData)
+	if err != nil {
+		log.Error("Failed to add onugem to kv store")
+		return err
+	}
+
+	log.Debugw("added onu to onugeminfo", log.Fields{"intf": IntfID, "onugem": onuGem})
+	return err
+}
+
+// UpdateOnuGemInfo updates Onuinfo on the kvstore per interface
+func (RsrcMgr *OpenOltResourceMgr) UpdateOnuGemInfo(ctx context.Context, IntfID uint32, onuGem []OnuGemInfo) error {
+
+	// TODO: VOL-2643
+	err := RsrcMgr.ResourceMgrs[IntfID].AddOnuGemInfo(ctx, IntfID, onuGem)
+	if err != nil {
+		log.Debugw("persistence-update-failed", log.Fields{
+			"interface-id": IntfID,
+			"gem-info":     onuGem,
+			"error":        err})
+		return err
+	}
+
+	log.Debugw("updated onugeminfo", log.Fields{"intf": IntfID, "onugem": onuGem})
+	return nil
+}
+
+// AddUniPortToOnuInfo adds uni port to the onuinfo kvstore. check if the uni is already present if not update the kv store.
+func (RsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, intfID uint32, onuID uint32, portNo uint32) {
+	var onuGemData []OnuGemInfo
+	var err error
+
+	if err = RsrcMgr.ResourceMgrs[intfID].GetOnuGemInfo(ctx, intfID, &onuGemData); err != nil {
+		log.Errorf("failed to get onuifo for intfid %d", intfID)
+		return
+	}
+	for idx, onu := range onuGemData {
+		if onu.OnuID == onuID {
+			for _, uni := range onu.UniPorts {
+				if uni == portNo {
+					log.Debugw("uni already present in onugem info", log.Fields{"uni": portNo})
+					return
+				}
+			}
+			onuGemData[idx].UniPorts = append(onuGemData[idx].UniPorts, portNo)
+			break
+		}
+	}
+	err = RsrcMgr.ResourceMgrs[intfID].AddOnuGemInfo(ctx, intfID, onuGemData)
+	if err != nil {
+		log.Errorw("Failed to add uin port in onugem to kv store", log.Fields{"uni": portNo})
+		return
+	}
+	return
+}
+
+//UpdateGemPortForPktIn updates gemport for pkt in path to kvstore, path being intfid, onuid, portno
+func (RsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
+
+	path := fmt.Sprintf(OnuPacketINPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort)
+	Value, err := json.Marshal(gemPort)
+	if err != nil {
+		log.Error("Failed to marshal data")
+		return
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
+		log.Errorw("Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
+		return
+	}
+	log.Debugw("added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
+
+	return
+}
+
+// GetGemPortFromOnuPktIn gets the gem port from onu pkt in path, path being intfid, onuid, portno
+func (RsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32) (uint32, error) {
+
+	var Val []byte
+	var gemPort uint32
+
+	path := fmt.Sprintf(OnuPacketINPath, intfID, onuID, logicalPort)
+
+	value, err := RsrcMgr.KVStore.Get(ctx, path)
+	if err != nil {
+		log.Errorw("Failed to get from kv store", log.Fields{"path": path})
+		return uint32(0), err
+	} else if value == nil {
+		log.Debugw("No pkt in gem found", log.Fields{"path": path})
+		return uint32(0), nil
+	}
+
+	if Val, err = kvstore.ToByte(value.Value); err != nil {
+		log.Error("Failed to convert to byte array")
+		return uint32(0), err
+	}
+	if err = json.Unmarshal(Val, &gemPort); err != nil {
+		log.Error("Failed to unmarshall")
+		return uint32(0), err
+	}
+	log.Debugw("found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
+
+	return gemPort, nil
+}
+
+// DelGemPortPktIn deletes the gemport from the pkt in path
+func (RsrcMgr *OpenOltResourceMgr) DelGemPortPktIn(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32) error {
+
+	path := fmt.Sprintf(OnuPacketINPath, intfID, onuID, logicalPort)
+	if err := RsrcMgr.KVStore.Delete(ctx, path); err != nil {
+		log.Errorf("Falied to remove resource %s", path)
+		return err
+	}
+	return nil
+}
+
+// DelOnuGemInfoForIntf deletes the onugem info from kvstore per interface
+func (RsrcMgr *OpenOltResourceMgr) DelOnuGemInfoForIntf(ctx context.Context, intfID uint32) error {
+	if err := RsrcMgr.ResourceMgrs[intfID].DelOnuGemInfoForIntf(ctx, intfID); err != nil {
+		log.Errorw("failed to delete onu gem info for", log.Fields{"intfid": intfID})
+		return err
+	}
+	return nil
+}
+
+//GetNNIFromKVStore gets NNi intfids from kvstore. path being per device
+func (RsrcMgr *OpenOltResourceMgr) GetNNIFromKVStore(ctx context.Context) ([]uint32, error) {
+
+	var nni []uint32
+	var Val []byte
+
+	path := fmt.Sprintf(NnniIntfID)
+	value, err := RsrcMgr.KVStore.Get(ctx, path)
+	if err != nil {
+		log.Error("failed to get data from kv store")
+		return nil, err
+	}
+	if value != nil {
+		if Val, err = kvstore.ToByte(value.Value); err != nil {
+			log.Error("Failed to convert to byte array")
+			return nil, err
+		}
+		if err = json.Unmarshal(Val, &nni); err != nil {
+			log.Error("Failed to unmarshall")
+			return nil, err
+		}
+	}
+	return nni, err
+}
+
+// AddNNIToKVStore adds Nni interfaces to kvstore, path being per device.
+func (RsrcMgr *OpenOltResourceMgr) AddNNIToKVStore(ctx context.Context, nniIntf uint32) error {
+	var Value []byte
+
+	nni, err := RsrcMgr.GetNNIFromKVStore(ctx)
+	if err != nil {
+		log.Error("failed to fetch nni interfaces from kv store")
+		return err
+	}
+
+	path := fmt.Sprintf(NnniIntfID)
+	nni = append(nni, nniIntf)
+	Value, err = json.Marshal(nni)
+	if err != nil {
+		log.Error("Failed to marshal data")
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
+		log.Errorw("Failed to put to kvstore", log.Fields{"path": path, "value": Value})
+		return err
+	}
+	log.Debugw("added nni to kv successfully", log.Fields{"path": path, "nni": nniIntf})
+	return nil
+}
+
+// DelNNiFromKVStore deletes nni interface list from kv store.
+func (RsrcMgr *OpenOltResourceMgr) DelNNiFromKVStore(ctx context.Context) error {
+
+	path := fmt.Sprintf(NnniIntfID)
+
+	if err := RsrcMgr.KVStore.Delete(ctx, path); err != nil {
+		log.Errorw("Failed to delete nni interfaces from kv store", log.Fields{"path": path})
+		return err
+	}
+	return nil
+}
+
+//UpdateFlowIDsForGem updates flow id per gemport
+func (RsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, intf uint32, gem uint32, flowIDs []uint32) error {
+	var val []byte
+	path := fmt.Sprintf(FlowIDsForGem, intf)
+
+	flowsForGem, err := RsrcMgr.GetFlowIDsGemMapForInterface(ctx, intf)
+	if err != nil {
+		log.Error("Failed to ger flowids for interface", log.Fields{"error": err, "intf": intf})
+		return err
+	}
+	if flowsForGem == nil {
+		flowsForGem = make(map[uint32][]uint32)
+	}
+	flowsForGem[gem] = flowIDs
+	val, err = json.Marshal(flowsForGem)
+	if err != nil {
+		log.Error("Failed to marshal data", log.Fields{"error": err})
+		return err
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, path, val); err != nil {
+		log.Errorw("Failed to put to kvstore", log.Fields{"error": err, "path": path, "value": val})
+		return err
+	}
+	log.Debugw("added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowsForGem[gem]})
+	return nil
+}
+
+//DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
+func (RsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) {
+	path := fmt.Sprintf(FlowIDsForGem, intf)
+	var val []byte
+
+	flowsForGem, err := RsrcMgr.GetFlowIDsGemMapForInterface(ctx, intf)
+	if err != nil {
+		log.Error("Failed to ger flowids for interface", log.Fields{"error": err, "intf": intf})
+		return
+	}
+	if flowsForGem == nil {
+		log.Error("No flowids found ", log.Fields{"intf": intf, "gemport": gem})
+		return
+	}
+	// once we get the flows per gem map from kv , just delete the gem entry from the map
+	delete(flowsForGem, gem)
+	// once gem entry is deleted update the kv store.
+	val, err = json.Marshal(flowsForGem)
+	if err != nil {
+		log.Error("Failed to marshal data", log.Fields{"error": err})
+		return
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, path, val); err != nil {
+		log.Errorw("Failed to put to kvstore", log.Fields{"error": err, "path": path, "value": val})
+		return
+	}
+	return
+}
+
+//GetFlowIDsGemMapForInterface gets flowids per gemport and interface
+func (RsrcMgr *OpenOltResourceMgr) GetFlowIDsGemMapForInterface(ctx context.Context, intf uint32) (map[uint32][]uint32, error) {
+	path := fmt.Sprintf(FlowIDsForGem, intf)
+	var flowsForGem map[uint32][]uint32
+	var val []byte
+
+	value, err := RsrcMgr.KVStore.Get(ctx, path)
+	if err != nil {
+		log.Error("failed to get data from kv store")
+		return nil, err
+	}
+	if value != nil && value.Value != nil {
+		if val, err = kvstore.ToByte(value.Value); err != nil {
+			log.Error("Failed to convert to byte array ", log.Fields{"error": err})
+			return nil, err
+		}
+		if err = json.Unmarshal(val, &flowsForGem); err != nil {
+			log.Error("Failed to unmarshall", log.Fields{"error": err})
+			return nil, err
+		}
+	}
+	return flowsForGem, nil
+}
+
+//DeleteIntfIDGempMapPath deletes the intf id path used to store flow ids per gem to kvstore.
+func (RsrcMgr *OpenOltResourceMgr) DeleteIntfIDGempMapPath(ctx context.Context, intf uint32) {
+	path := fmt.Sprintf(FlowIDsForGem, intf)
+	if err := RsrcMgr.KVStore.Delete(ctx, path); err != nil {
+		log.Errorw("Failed to delete nni interfaces from kv store", log.Fields{"path": path})
+		return
+	}
+	return
+}
+
+// RemoveResourceMap Clear resource map associated with (intfid, onuid, uniid) tuple.
+func (RsrcMgr *OpenOltResourceMgr) RemoveResourceMap(ctx context.Context, intfID uint32, onuID int32, uniID int32) {
+	IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
+	RsrcMgr.ResourceMgrs[intfID].RemoveResourceMap(ctx, IntfOnuIDUniID)
+}
+
+//GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
+func (RsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
+	path := fmt.Sprintf(McastQueuesForIntf)
+	var mcastQueueToIntfMap map[uint32][]uint32
+	var val []byte
+
+	kvPair, err := RsrcMgr.KVStore.Get(ctx, path)
+	if err != nil {
+		log.Error("failed to get data from kv store")
+		return nil, err
+	}
+	if kvPair != nil && kvPair.Value != nil {
+		if val, err = kvstore.ToByte(kvPair.Value); err != nil {
+			log.Error("Failed to convert to byte array ", log.Fields{"error": err})
+			return nil, err
+		}
+		if err = json.Unmarshal(val, &mcastQueueToIntfMap); err != nil {
+			log.Error("Failed to unmarshall ", log.Fields{"error": err})
+			return nil, err
+		}
+	}
+	return mcastQueueToIntfMap, nil
+}
+
+//AddMcastQueueForIntf adds multicast queue for pon interface
+func (RsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, intf uint32, gem uint32, servicePriority uint32) error {
+	var val []byte
+	path := fmt.Sprintf(McastQueuesForIntf)
+
+	mcastQueues, err := RsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
+	if err != nil {
+		log.Errorw("Failed to get multicast queue info for interface", log.Fields{"error": err, "intf": intf})
+		return err
+	}
+	if mcastQueues == nil {
+		mcastQueues = make(map[uint32][]uint32)
+	}
+	mcastQueues[intf] = []uint32{gem, servicePriority}
+	if val, err = json.Marshal(mcastQueues); err != nil {
+		log.Errorw("Failed to marshal data", log.Fields{"error": err})
+		return err
+	}
+	if err = RsrcMgr.KVStore.Put(ctx, path, val); err != nil {
+		log.Errorw("Failed to put to kvstore", log.Fields{"error": err, "path": path, "value": val})
+		return err
+	}
+	log.Debugw("added multicast queue info to KV store successfully", log.Fields{"path": path, "mcastQueueInfo": mcastQueues[intf], "interfaceId": intf})
+	return nil
+}
+
+//AddFlowGroupToKVStore adds flow group into KV store
+func (RsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
+	var Value []byte
+	var err error
+	var path string
+	if cached {
+		path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
+	} else {
+		path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
+	}
+	//build group info object
+	var outPorts []uint32
+	for _, ofBucket := range groupEntry.Desc.Buckets {
+		for _, ofAction := range ofBucket.Actions {
+			if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
+				outPorts = append(outPorts, ofAction.GetOutput().Port)
+			}
+		}
+	}
+	groupInfo := GroupInfo{
+		GroupID:  groupEntry.Desc.GroupId,
+		OutPorts: outPorts,
+	}
+
+	Value, err = json.Marshal(groupInfo)
+
+	if err != nil {
+		log.Error("failed to Marshal flow group object")
+		return err
+	}
+
+	if err = RsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
+		log.Errorf("Failed to update resource %s", path)
+		return err
+	}
+	return nil
+}
+
+//RemoveFlowGroupFromKVStore removes flow group from KV store
+func (RsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) bool {
+	var path string
+	if cached {
+		path = fmt.Sprintf(FlowGroupCached, groupID)
+	} else {
+		path = fmt.Sprintf(FlowGroup, groupID)
+	}
+	if err := RsrcMgr.KVStore.Delete(ctx, path); err != nil {
+		log.Errorf("Failed to remove resource %s due to %s", path, err)
+		return false
+	}
+	return true
+}
+
+//GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
+//fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
+// Returns (false, {}, nil) if the group does not exists in the KV store.
+func (RsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
+	var groupInfo GroupInfo
+	var path string
+	if cached {
+		path = fmt.Sprintf(FlowGroupCached, groupID)
+	} else {
+		path = fmt.Sprintf(FlowGroup, groupID)
+	}
+	kvPair, err := RsrcMgr.KVStore.Get(ctx, path)
+	if err != nil {
+		return false, groupInfo, err
+	}
+	if kvPair != nil && kvPair.Value != nil {
+		Val, err := kvstore.ToByte(kvPair.Value)
+		if err != nil {
+			log.Errorw("Failed to convert flow group into byte array", log.Fields{"error": err})
+			return false, groupInfo, err
+		}
+		if err = json.Unmarshal(Val, &groupInfo); err != nil {
+			log.Errorw("Failed to unmarshal", log.Fields{"error": err})
+			return false, groupInfo, err
+		}
+		return true, groupInfo, nil
+	}
+	return false, groupInfo, nil
+}
diff --git a/internal/pkg/resourcemanager/resourcemanager_test.go b/internal/pkg/resourcemanager/resourcemanager_test.go
new file mode 100644
index 0000000..5d96cc3
--- /dev/null
+++ b/internal/pkg/resourcemanager/resourcemanager_test.go
@@ -0,0 +1,1183 @@
+/*
+ * 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.
+ */
+
+/*
+This file contains unit test cases for functions in the file resourcemanager.go.
+This file also implements the Client interface to mock the kv-client, fields struct to mock OpenOltResourceMgr
+and few utility functions.
+*/
+
+//Package adaptercore provides the utility for olt devices, flows and statistics
+package resourcemanager
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
+	fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ponrmgr "github.com/opencord/voltha-lib-go/v3/pkg/ponresourcemanager"
+	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/openolt"
+	"reflect"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+)
+
+func init() {
+	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
+}
+
+const (
+	// MeterConfig meter to extract meter
+	MeterConfig = "meter_id"
+	// TpIDSuffixPath to extract Techprofile
+	TpIDSuffixPath = "tp_id"
+	// FlowIDInfo to extract flows
+	FlowIDInfo = "flow_id_info"
+	// FlowIds to extract flows
+	FlowIDs = "flow_ids"
+	// GemportIDs to gemport_ids
+	GemportIDs = "gemport_ids"
+	// AllocIDs to extract alloc_ids
+	AllocIDs = "alloc_ids"
+	// GemportIDPool to extract gemport
+	GemportIDPool = "gemport_id_pool"
+	// AllocIDPool to extract allocid
+	AllocIDPool = "alloc_id_pool"
+	// FlowIDpool to extract Flow ids
+	FlowIDpool = "flow_id_pool"
+)
+
+// fields mocks  OpenOltResourceMgr struct.
+type fields struct {
+	DeviceID     string
+	HostAndPort  string
+	Args         string
+	KVStore      *db.Backend
+	DeviceType   string
+	Host         string
+	Port         int
+	DevInfo      *openolt.DeviceInfo
+	ResourceMgrs map[uint32]*ponrmgr.PONResourceManager
+}
+
+// MockKVClient mocks the AdapterProxy interface.
+type MockResKVClient struct {
+}
+
+// getResMgr mocks OpenOltResourceMgr struct.
+func getResMgr() *fields {
+	var resMgr fields
+	resMgr.KVStore = &db.Backend{
+		Client: &MockResKVClient{},
+	}
+	resMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager)
+	ranges := make(map[string]interface{})
+	sharedIdxByType := make(map[string]string)
+	sharedIdxByType["ALLOC_ID"] = "ALLOC_ID"
+	sharedIdxByType["ONU_ID"] = "ONU_ID"
+	sharedIdxByType["GEMPORT_ID"] = "GEMPORT_ID"
+	sharedIdxByType["FLOW_ID"] = "FLOW_ID"
+	ranges["ONU_ID"] = uint32(0)
+	ranges["GEMPORT_ID"] = uint32(0)
+	ranges["ALLOC_ID"] = uint32(0)
+	ranges["FLOW_ID"] = uint32(0)
+	ranges["onu_id_shared"] = uint32(0)
+	ranges["alloc_id_shared"] = uint32(0)
+	ranges["gemport_id_shared"] = uint32(0)
+	ranges["flow_id_shared"] = uint32(0)
+	ponMgr := &ponrmgr.PONResourceManager{
+		DeviceID: "onu-1",
+		IntfIDs:  []uint32{1, 2},
+		KVStore: &db.Backend{
+			Client: &MockResKVClient{},
+		},
+		PonResourceRanges: ranges,
+		SharedIdxByType:   sharedIdxByType,
+	}
+	resMgr.ResourceMgrs[1] = ponMgr
+	resMgr.ResourceMgrs[2] = ponMgr
+	return &resMgr
+}
+
+// List function implemented for KVClient.
+func (kvclient *MockResKVClient) List(ctx context.Context, key string) (map[string]*kvstore.KVPair, error) {
+	return nil, errors.New("key didn't find")
+}
+
+// Get mock function implementation for KVClient
+func (kvclient *MockResKVClient) Get(ctx context.Context, key string) (*kvstore.KVPair, error) {
+	log.Debugw("Warning Warning Warning: Get of MockKVClient called", log.Fields{"key": key})
+	if key != "" {
+		if strings.Contains(key, MeterConfig) {
+			var bands []*ofp.OfpMeterBandHeader
+			bands = append(bands, &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DSCP_REMARK,
+				Rate: 1024, Data: &ofp.OfpMeterBandHeader_DscpRemark{DscpRemark: &ofp.OfpMeterBandDscpRemark{PrecLevel: 2}}})
+
+			bands = append(bands, &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DSCP_REMARK,
+				Rate: 1024, Data: &ofp.OfpMeterBandHeader_DscpRemark{DscpRemark: &ofp.OfpMeterBandDscpRemark{PrecLevel: 3}}})
+
+			sep := strings.Split(key, "/")[1]
+			val, _ := strconv.ParseInt(strings.Split(sep, ",")[1], 10, 32)
+			if uint32(val) > 1 {
+				meterConfig := &ofp.OfpMeterConfig{MeterId: uint32(val), Bands: bands}
+				str, _ := json.Marshal(meterConfig)
+
+				return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
+			}
+			return nil, errors.New("invalid meter")
+		}
+		if strings.Contains(key, FlowIDpool) || strings.Contains(key, GemportIDPool) || strings.Contains(key, AllocIDPool) {
+			log.Debug("Error Error Error Key:", FlowIDpool, GemportIDPool, AllocIDPool)
+			data := make(map[string]interface{})
+			data["pool"] = "1024"
+			data["start_idx"] = 1
+			data["end_idx"] = 1024
+			str, _ := json.Marshal(data)
+			return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
+		}
+		if strings.Contains(key, FlowIDInfo) || strings.Contains(key, FlowIDs) {
+			log.Debug("Error Error Error Key:", FlowIDs, FlowIDInfo)
+			str, _ := json.Marshal([]uint32{1, 2})
+			return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
+		}
+		if strings.Contains(key, AllocIDs) || strings.Contains(key, GemportIDs) {
+			log.Debug("Error Error Error Key:", AllocIDs, GemportIDs)
+			str, _ := json.Marshal(1)
+			return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
+		}
+		if strings.Contains(key, McastQueuesForIntf) {
+			log.Debug("Error Error Error Key:", McastQueuesForIntf)
+			mcastQueues := make(map[uint32][]uint32)
+			mcastQueues[10] = []uint32{4000, 0}
+			str, _ := json.Marshal(mcastQueues)
+			return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
+		}
+		if strings.Contains(key, "flow_groups") && !strings.Contains(key, "1000") {
+			groupInfo := GroupInfo{GroupID: 2, OutPorts: []uint32{2}}
+			str, _ := json.Marshal(groupInfo)
+			return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil
+		}
+
+		maps := make(map[string]*kvstore.KVPair)
+		maps[key] = &kvstore.KVPair{Key: key}
+		return maps[key], nil
+	}
+	return nil, errors.New("key didn't find")
+}
+
+// Put mock function implementation for KVClient
+func (kvclient *MockResKVClient) Put(ctx context.Context, key string, value interface{}) error {
+	if key != "" {
+		return nil
+	}
+	return errors.New("key didn't find")
+}
+
+// Delete mock function implementation for KVClient
+func (kvclient *MockResKVClient) Delete(ctx context.Context, key string) error {
+	return nil
+}
+
+// Reserve mock function implementation for KVClient
+func (kvclient *MockResKVClient) Reserve(ctx context.Context, key string, value interface{}, ttl int64) (interface{}, error) {
+	return nil, errors.New("key didn't find")
+}
+
+// ReleaseReservation mock function implementation for KVClient
+func (kvclient *MockResKVClient) ReleaseReservation(ctx context.Context, key string) error {
+	return nil
+}
+
+// ReleaseAllReservations mock function implementation for KVClient
+func (kvclient *MockResKVClient) ReleaseAllReservations(ctx context.Context) error {
+	return nil
+}
+
+// RenewReservation mock function implementation for KVClient
+func (kvclient *MockResKVClient) RenewReservation(ctx context.Context, key string) error {
+	return nil
+}
+
+// Watch mock function implementation for KVClient
+func (kvclient *MockResKVClient) Watch(ctx context.Context, key string, withPrefix bool) chan *kvstore.Event {
+	return nil
+}
+
+// AcquireLock mock function implementation for KVClient
+func (kvclient *MockResKVClient) AcquireLock(ctx context.Context, lockName string, timeout int) error {
+	return nil
+}
+
+// ReleaseLock mock function implementation for KVClient
+func (kvclient *MockResKVClient) ReleaseLock(lockName string) error {
+	return nil
+}
+
+// IsConnectionUp mock function implementation for KVClient
+func (kvclient *MockResKVClient) IsConnectionUp(ctx context.Context) bool { // timeout in second
+	return true
+}
+
+// CloseWatch mock function implementation for KVClient
+func (kvclient *MockResKVClient) CloseWatch(key string, ch chan *kvstore.Event) {
+}
+
+// Close mock function implementation for KVClient
+func (kvclient *MockResKVClient) Close() {
+}
+
+// testResMgrObject maps fields type to OpenOltResourceMgr type.
+func testResMgrObject(testResMgr *fields) *OpenOltResourceMgr {
+	return &OpenOltResourceMgr{
+		DeviceID:     testResMgr.DeviceID,
+		HostAndPort:  testResMgr.HostAndPort,
+		Args:         testResMgr.Args,
+		KVStore:      testResMgr.KVStore,
+		DeviceType:   testResMgr.DeviceType,
+		Host:         testResMgr.Host,
+		Port:         testResMgr.Port,
+		DevInfo:      testResMgr.DevInfo,
+		ResourceMgrs: testResMgr.ResourceMgrs,
+	}
+}
+
+func TestNewResourceMgr(t *testing.T) {
+	type args struct {
+		deviceID        string
+		KVStoreHostPort string
+		kvStoreType     string
+		deviceType      string
+		devInfo         *openolt.DeviceInfo
+	}
+	tests := []struct {
+		name string
+		args args
+		want *OpenOltResourceMgr
+	}{
+		{"NewResourceMgr-1", args{"olt1", "1:2", "consul",
+			"onu", &openolt.DeviceInfo{OnuIdStart: 1, OnuIdEnd: 1}}, &OpenOltResourceMgr{}},
+		{"NewResourceMgr-2", args{"olt2", "3:4", "etcd",
+			"onu", &openolt.DeviceInfo{OnuIdStart: 1, OnuIdEnd: 1}}, &OpenOltResourceMgr{}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := NewResourceMgr(ctx, tt.args.deviceID, tt.args.KVStoreHostPort, tt.args.kvStoreType, tt.args.deviceType, tt.args.devInfo); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("NewResourceMgr() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_Delete(t *testing.T) {
+	tests := []struct {
+		name    string
+		fields  *fields
+		wantErr error
+	}{
+		{"Delete-1", getResMgr(), errors.New("failed to clear device resource pool")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.Delete(ctx); (err != nil) && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("Delete() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_FreeFlowID(t *testing.T) {
+	type args struct {
+		IntfID uint32
+		onuID  int32
+		uniID  int32
+		FlowID uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+	}{
+		{"FreeFlowID-1", getResMgr(), args{2, 2, 2, 2}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			RsrcMgr.FreeFlowID(ctx, tt.args.IntfID, tt.args.onuID, tt.args.uniID, tt.args.FlowID)
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_FreeFlowIDs(t *testing.T) {
+
+	type args struct {
+		IntfID uint32
+		onuID  uint32
+		uniID  uint32
+		FlowID []uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+	}{
+		{"FreeFlowIDs-1", getResMgr(), args{2, 2, 2, []uint32{1, 2}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			RsrcMgr.FreeFlowIDs(ctx, tt.args.IntfID, tt.args.onuID, tt.args.uniID, tt.args.FlowID)
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_FreePONResourcesForONU(t *testing.T) {
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+	}{
+		{"FreePONResourcesForONU-1", getResMgr(), args{2, 0, 2}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			RsrcMgr.FreePONResourcesForONU(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID)
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_FreeonuID(t *testing.T) {
+	type args struct {
+		intfID uint32
+		onuID  []uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+	}{
+		{"FreeOnuID-1", getResMgr(), args{2, []uint32{1, 2}}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			RsrcMgr.FreeonuID(ctx, tt.args.intfID, tt.args.onuID)
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetAllocID(t *testing.T) {
+
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+		want   uint32
+	}{
+		{"GetAllocID-1", getResMgr(), args{2, 2, 2}, 0},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := RsrcMgr.GetAllocID(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("GetAllocID() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetCurrentAllocIDForOnu(t *testing.T) {
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+		want   []uint32
+	}{
+		{"GetCurrentAllocIDForOnu-1", getResMgr(), args{2, 2, 2}, []uint32{}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := RsrcMgr.GetCurrentAllocIDsForOnu(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetCurrentAllocIDsForOnu() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetCurrentFlowIDsForOnu(t *testing.T) {
+
+	type args struct {
+		PONIntfID uint32
+		ONUID     int32
+		UNIID     int32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+		want   []uint32
+	}{
+		{"GetCurrentFlowIDsForOnu-1", getResMgr(), args{2, 2, 2}, []uint32{}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := RsrcMgr.GetCurrentFlowIDsForOnu(ctx, tt.args.PONIntfID, tt.args.ONUID, tt.args.UNIID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("GetCurrentFlowIDsForOnu() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetCurrentGEMPortIDsForOnu(t *testing.T) {
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+		want   []uint32
+	}{
+		{"GetCurrentGEMPortIDsForOnu-1", getResMgr(), args{2, 2, 2}, []uint32{}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := RsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("GetCurrentGEMPortIDsForOnu() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetFlowID(t *testing.T) {
+
+	type args struct {
+		ponIntfID       uint32
+		ONUID           int32
+		uniID           int32
+		gemportID       uint32
+		flowStoreCookie uint64
+		flowCategory    string
+		vlanPcp         []uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    uint32
+		wantErr error
+	}{
+		{"GetFlowID-1", getResMgr(), args{2, 2, 2, 2, 2,
+			"HSIA", nil}, 0, errors.New("failed to get flows")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			got, err := RsrcMgr.GetFlowID(ctx, tt.args.ponIntfID, tt.args.ONUID, tt.args.uniID, tt.args.gemportID, tt.args.flowStoreCookie, tt.args.flowCategory, tt.args.vlanPcp...)
+			if err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("GetFlowID() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("GetFlowID() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetGEMPortID(t *testing.T) {
+	type args struct {
+		ponPort    uint32
+		onuID      uint32
+		uniID      uint32
+		NumOfPorts uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    []uint32
+		wantErr error
+	}{
+		{"GetGEMPortID-1", getResMgr(), args{2, 2, 2, 2}, []uint32{},
+			errors.New("failed to get gem port")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			got, err := RsrcMgr.GetGEMPortID(ctx, tt.args.ponPort, tt.args.onuID, tt.args.uniID, tt.args.NumOfPorts)
+			if reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil {
+				t.Errorf("GetGEMPortID() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("GetGEMPortID() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetMeterIDForOnu(t *testing.T) {
+	type args struct {
+		Direction string
+		IntfID    uint32
+		OnuID     uint32
+		UniID     uint32
+		tpID      uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    *ofp.OfpMeterConfig
+		wantErr error
+	}{
+		{"GetMeterIDOnu", getResMgr(), args{"DOWNSTREAM", 1, 1, 1, 64},
+			&ofp.OfpMeterConfig{}, errors.New("failed to get Meter config from kvstore for path")},
+		{"GetMeterIDOnu", getResMgr(), args{"DOWNSTREAM", 2, 2, 2, 65},
+			&ofp.OfpMeterConfig{}, errors.New("failed to get Meter config from kvstore for path")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			got, err := RsrcMgr.GetMeterIDForOnu(ctx, tt.args.Direction, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, tt.args.tpID)
+			if reflect.TypeOf(got) != reflect.TypeOf(tt.want) && err != nil {
+				t.Errorf("GetMeterIDForOnu() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetONUID(t *testing.T) {
+	type args struct {
+		ponIntfID uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		want    uint32
+		wantErr error
+	}{
+		{"GetONUID-1", getResMgr(), args{2}, uint32(0), errors.New("json errors")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			got, err := RsrcMgr.GetONUID(ctx, tt.args.ponIntfID)
+			if got != tt.want && err != nil {
+				t.Errorf("GetONUID() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetTechProfileIDForOnu(t *testing.T) {
+
+	type args struct {
+		IntfID uint32
+		OnuID  uint32
+		UniID  uint32
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+		want   []uint32
+	}{
+		{"GetTechProfileIDForOnu-1", getResMgr(), args{2, 2, 2},
+			[]uint32{1}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := RsrcMgr.GetTechProfileIDForOnu(ctx, tt.args.IntfID, tt.args.OnuID, tt.args.UniID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("GetTechProfileIDForOnu() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_IsFlowCookieOnKVStore(t *testing.T) {
+	type args struct {
+		ponIntfID       uint32
+		onuID           int32
+		uniID           int32
+		flowStoreCookie uint64
+	}
+	tests := []struct {
+		name   string
+		fields *fields
+		args   args
+		want   bool
+	}{
+		{"IsFlowCookieOnKVStore-1", getResMgr(), args{2, 2, 2, 2}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if got := RsrcMgr.IsFlowCookieOnKVStore(ctx, tt.args.ponIntfID, tt.args.onuID, tt.args.uniID, tt.args.flowStoreCookie); got != tt.want {
+				t.Errorf("IsFlowCookieOnKVStore() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_RemoveMeterIDForOnu(t *testing.T) {
+
+	type args struct {
+		Direction string
+		IntfID    uint32
+		OnuID     uint32
+		UniID     uint32
+		tpID      uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"RemoveMeterIdForOnu-1", getResMgr(), args{"DOWNSTREAM", 1, 1, 1, 64},
+			errors.New("failed to delete meter id %s from kvstore")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.RemoveMeterIDForOnu(ctx, tt.args.Direction, tt.args.IntfID, tt.args.OnuID, tt.args.UniID,
+				tt.args.tpID); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil {
+				t.Errorf("RemoveMeterIDForOnu() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_RemoveTechProfileIDForOnu(t *testing.T) {
+	type args struct {
+		IntfID uint32
+		OnuID  uint32
+		UniID  uint32
+		tpID   uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"RemoveTechProfileIDForOnu-1", getResMgr(), args{2, 2, 2, 64},
+			errors.New("failed to delete techprofile id resource %s in KV store")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.RemoveTechProfileIDForOnu(ctx, tt.args.IntfID, tt.args.OnuID, tt.args.UniID,
+				tt.args.tpID); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil {
+				t.Errorf("RemoveTechProfileIDForOnu() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_UpdateAllocIdsForOnu(t *testing.T) {
+	type args struct {
+		ponPort uint32
+		onuID   uint32
+		uniID   uint32
+		allocID []uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"UpdateAllocIdsForOnu-1", getResMgr(), args{2, 2, 2, []uint32{1, 2}},
+			errors.New("")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.UpdateAllocIdsForOnu(ctx, tt.args.ponPort, tt.args.onuID, tt.args.uniID, tt.args.allocID); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("UpdateAllocIdsForOnu() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_UpdateFlowIDInfo(t *testing.T) {
+	type args struct {
+		ponIntfID int32
+		onuID     int32
+		uniID     int32
+		flowID    uint32
+		flowData  *[]FlowInfo
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"UpdateFlowIDInfo-1", getResMgr(), args{2, 2, 2, 2, &[]FlowInfo{}}, errors.New("")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.UpdateFlowIDInfo(ctx, tt.args.ponIntfID, tt.args.onuID, tt.args.uniID, tt.args.flowID, tt.args.flowData); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("UpdateFlowIDInfo() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_UpdateGEMPortIDsForOnu(t *testing.T) {
+
+	type args struct {
+		ponPort     uint32
+		onuID       uint32
+		uniID       uint32
+		GEMPortList []uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"UpdateGEMPortIDsForOnu-1", getResMgr(), args{2, 2, 2,
+			[]uint32{1, 2}}, errors.New("failed to update resource")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.UpdateGEMPortIDsForOnu(ctx, tt.args.ponPort, tt.args.onuID, tt.args.uniID, tt.args.GEMPortList); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("UpdateGEMPortIDsForOnu() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_UpdateGEMportsPonportToOnuMapOnKVStore(t *testing.T) {
+	type args struct {
+		gemPorts []uint32
+		PonPort  uint32
+		onuID    uint32
+		uniID    uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"UpdateGEMportsPonportToOnuMapOnKVStore-1", getResMgr(), args{[]uint32{1, 2},
+			2, 2, 2}, errors.New("failed to update resource")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, tt.args.gemPorts, tt.args.PonPort,
+				tt.args.onuID, tt.args.uniID); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("UpdateGEMportsPonportToOnuMapOnKVStore() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_UpdateMeterIDForOnu(t *testing.T) {
+	type args struct {
+		Direction   string
+		IntfID      uint32
+		OnuID       uint32
+		UniID       uint32
+		tpID        uint32
+		MeterConfig *ofp.OfpMeterConfig
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"UpdateMeterIDForOnu-1", getResMgr(), args{"DOWNSTREAM", 2, 2,
+			2, 64, &ofp.OfpMeterConfig{}}, errors.New("failed to get Meter config from kvstore for path")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.UpdateMeterIDForOnu(ctx, tt.args.Direction, tt.args.IntfID, tt.args.OnuID, tt.args.UniID,
+				tt.args.tpID, tt.args.MeterConfig); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil {
+				t.Errorf("UpdateMeterIDForOnu() got = %v, want %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_UpdateTechProfileIDForOnu(t *testing.T) {
+	type args struct {
+		IntfID uint32
+		OnuID  uint32
+		UniID  uint32
+		TpID   uint32
+	}
+	tests := []struct {
+		name    string
+		fields  *fields
+		args    args
+		wantErr error
+	}{
+		{"UpdateTechProfileIDForOnu-1", getResMgr(), args{2, 2, 2,
+			2}, errors.New("failed to update resource")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			if err := RsrcMgr.UpdateTechProfileIDForOnu(ctx, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, tt.args.TpID); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil {
+				t.Errorf("UpdateTechProfileIDForOnu() got = %v, want %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestSetKVClient(t *testing.T) {
+	type args struct {
+		backend  string
+		Host     string
+		Port     int
+		DeviceID string
+	}
+	tests := []struct {
+		name string
+		args args
+		want *db.Backend
+	}{
+		{"setKVClient-1", args{"consul", "1.1.1.1", 1, "olt1"}, &db.Backend{}},
+		{"setKVClient-1", args{"etcd", "2.2.2.2", 2, "olt2"}, &db.Backend{}},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := SetKVClient(tt.args.backend, tt.args.Host, tt.args.Port, tt.args.DeviceID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("SetKVClient() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_getFlowIDFromFlowInfo(t *testing.T) {
+	type args struct {
+		FlowInfo        *[]FlowInfo
+		flowID          uint32
+		gemportID       uint32
+		flowStoreCookie uint64
+		flowCategory    string
+		vlanPcp         []uint32
+	}
+	flowInfo := &[]FlowInfo{
+		{
+			&openolt.Flow{
+				FlowId:    1,
+				GemportId: 1,
+				Classifier: &openolt.Classifier{
+					OPbits: 1,
+				}},
+			1,
+			"HSIA_FLOW",
+			2000,
+		},
+		{
+			&openolt.Flow{
+				GemportId: 1,
+			},
+			1,
+			"EAPOL",
+			3000,
+		},
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr error
+	}{
+		{"getFlowIdFromFlowInfo-1", args{}, errors.New("invalid flow-info")},
+		{"getFlowIdFromFlowInfo-2", args{flowInfo, 1, 1, 1,
+			"HSIA_FLOW", []uint32{1, 2}}, errors.New("invalid flow-info")},
+		{"getFlowIdFromFlowInfo-2", args{flowInfo, 1, 1, 1,
+			"EAPOL", []uint32{1, 2}}, errors.New("invalid flow-info")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			err := getFlowIDFromFlowInfo(tt.args.FlowInfo, tt.args.flowID, tt.args.gemportID, tt.args.flowStoreCookie, tt.args.flowCategory, tt.args.vlanPcp...)
+			if reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil {
+				t.Errorf("getFlowIDFromFlowInfo() error = %v, wantErr %v", err, tt.wantErr)
+			}
+			if err == nil {
+				t.Log("return'd nil")
+			}
+		})
+	}
+}
+
+func Test_newKVClient(t *testing.T) {
+	type args struct {
+		storeType string
+		address   string
+		timeout   uint32
+	}
+	var kvClient kvstore.Client
+	tests := []struct {
+		name    string
+		args    args
+		want    kvstore.Client
+		wantErr error
+	}{
+		{"newKVClient-1", args{"", "3.3.3.3", 1}, kvClient, errors.New("unsupported-kv-store")},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := newKVClient(tt.args.storeType, tt.args.address, tt.args.timeout)
+			if got != nil && reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
+				t.Errorf("newKVClient() got = %v, want %v", got, tt.want)
+			}
+			if (err != nil) && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) {
+				t.Errorf("newKVClient() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_AddMcastQueueForIntf(t *testing.T) {
+	type args struct {
+		intf            uint32
+		gem             uint32
+		servicePriority uint32
+	}
+	tests := []struct {
+		name   string
+		args   args
+		fields *fields
+	}{
+		{"AddMcastQueueForIntf-1", args{0, 4000, 0}, getResMgr()},
+		{"AddMcastQueueForIntf-2", args{1, 4000, 1}, getResMgr()},
+		{"AddMcastQueueForIntf-3", args{2, 4000, 2}, getResMgr()},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			err := RsrcMgr.AddMcastQueueForIntf(ctx, tt.args.intf, tt.args.gem, tt.args.servicePriority)
+			if err != nil {
+				t.Errorf("%s got err= %s wants nil", tt.name, err)
+				return
+			}
+		})
+	}
+}
+
+func newGroup(groupID uint32, outPorts []uint32) *ofp.OfpGroupEntry {
+	groupDesc := ofp.OfpGroupDesc{
+		Type:    ofp.OfpGroupType_OFPGT_ALL,
+		GroupId: groupID,
+	}
+	groupEntry := ofp.OfpGroupEntry{
+		Desc: &groupDesc,
+	}
+	for i := 0; i < len(outPorts); i++ {
+		var acts []*ofp.OfpAction
+		acts = append(acts, fu.Output(outPorts[i]))
+		bucket := ofp.OfpBucket{
+			Actions: acts,
+		}
+		groupDesc.Buckets = append(groupDesc.Buckets, &bucket)
+	}
+	return &groupEntry
+}
+
+func TestOpenOltResourceMgr_AddFlowGroupToKVStore(t *testing.T) {
+	type args struct {
+		group  *ofp.OfpGroupEntry
+		cached bool
+	}
+	//create group 1
+	group1 := newGroup(1, []uint32{1})
+	//create group 2
+	group2 := newGroup(2, []uint32{2})
+	//define test set
+	tests := []struct {
+		name   string
+		args   args
+		fields *fields
+	}{
+		{"AddFlowGroupToKVStore-1", args{group1, true}, getResMgr()},
+		{"AddFlowGroupToKVStore-2", args{group2, false}, getResMgr()},
+	}
+	//execute tests
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			err := RsrcMgr.AddFlowGroupToKVStore(ctx, tt.args.group, tt.args.cached)
+			if err != nil {
+				t.Errorf("%s got err= %s wants nil", tt.name, err)
+				return
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_RemoveFlowGroupFromKVStore(t *testing.T) {
+	type args struct {
+		groupID uint32
+		cached  bool
+	}
+	//define test set
+	tests := []struct {
+		name   string
+		args   args
+		fields *fields
+	}{
+		{"RemoveFlowGroupFromKVStore-1", args{1, true}, getResMgr()},
+		{"RemoveFlowGroupFromKVStore-2", args{2, false}, getResMgr()},
+	}
+	//execute tests
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			success := RsrcMgr.RemoveFlowGroupFromKVStore(ctx, tt.args.groupID, tt.args.cached)
+			if !success {
+				t.Errorf("%s got false but wants true", tt.name)
+				return
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetFlowGroupFromKVStore(t *testing.T) {
+	type args struct {
+		groupID uint32
+		cached  bool
+	}
+	//define test set
+	tests := []struct {
+		name   string
+		args   args
+		fields *fields
+	}{
+		{"GetFlowGroupFromKVStore-1", args{1, true}, getResMgr()},
+		{"GetFlowGroupFromKVStore-2", args{2, false}, getResMgr()},
+		{"GetFlowGroupFromKVStore-3", args{1000, false}, getResMgr()},
+	}
+	//execute tests
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			exists, groupInfo, err := RsrcMgr.GetFlowGroupFromKVStore(ctx, tt.args.groupID, tt.args.cached)
+			if err != nil {
+				t.Errorf("%s got error but wants nil error", tt.name)
+				return
+			} else if exists && (groupInfo.GroupID == 0) {
+				t.Errorf("%s got true and nil group info but expected not nil group info", tt.name)
+				return
+			} else if tt.args.groupID == 3 && exists {
+				t.Errorf("%s got true but wants false", tt.name)
+				return
+			}
+		})
+	}
+}
