diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go
new file mode 100644
index 0000000..6be3ebc
--- /dev/null
+++ b/internal/pkg/config/config.go
@@ -0,0 +1,209 @@
+/*
+* 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"
+	"os"
+	"time"
+)
+
+// Open ONU default constants
+const (
+	etcdStoreName               = "etcd"
+	defaultInstanceid           = "epononu"
+	defaultKafkaadapterhost     = "172.30.254.100"
+	defaultKafkaadapterport     = 9092
+	defaultKafkaclusterhost     = "172.30.254.100"
+	defaultKafkaclusterport     = 9092
+	defaultKvstoretype          = etcdStoreName
+	defaultKvstoretimeout       = 5 * time.Second
+	defaultKvstorehost          = "localhost"
+	defaultKvstoreport          = 2379 // Consul = 8500; Etcd = 2379
+	defaultLoglevel             = "DEBUG"
+	defaultBanner               = false
+	defaultDisplayVersionOnly   = false
+	defaultAccIncrEvto          = false
+	defaultTopic                = "epononu"
+	defaultCoretopic            = "rwcore"
+	defaultEventtopic           = "voltha.events"
+	defaultOnunumber            = 1
+	defaultProbeHost            = ""
+	defaultProbePort            = 8080
+	defaultLiveProbeInterval    = 60 * time.Second
+	defaultNotLiveProbeInterval = 5 * time.Second // Probe more frequently when not alive
+	defaultHearbeatCheckInterval = 30 * time.Second
+	defaultHearbeatFailReportInterval = 180 * time.Second
+	defaultKafkaReconnectRetries = -1
+	defaultCurrentReplica        = 1
+	defaultTotalReplicas         = 1
+)
+
+// AdapterFlags represents the set of configurations used by the read-write adaptercore service
+type AdapterFlags struct {
+	InstanceID                  string
+	KafkaAdapterHost            string
+	KafkaAdapterPort            int
+	KafkaClusterHost            string
+	KafkaClusterPort            int
+	KVStoreType                 string
+	KVStoreTimeout              time.Duration
+	KVStoreHost                 string
+	KVStorePort                 int
+	Topic                       string
+	CoreTopic                   string
+	EventTopic                  string
+	LogLevel                    string
+	OnuNumber                   int
+	Banner                      bool
+	DisplayVersionOnly          bool
+	AccIncrEvto                 bool
+	ProbeHost                   string
+	ProbePort                   int
+	LiveProbeInterval           time.Duration
+	NotLiveProbeInterval        time.Duration
+	HeartbeatCheckInterval      time.Duration
+	HeartbeatFailReportInterval time.Duration
+	KafkaReconnectRetries       int
+	CurrentReplica              int
+	TotalReplicas               int
+}
+
+// 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,
+		AccIncrEvto:                 defaultAccIncrEvto,
+		ProbeHost:                   defaultProbeHost,
+		ProbePort:                   defaultProbePort,
+		LiveProbeInterval:           defaultLiveProbeInterval,
+		NotLiveProbeInterval:        defaultNotLiveProbeInterval,
+		HeartbeatCheckInterval:      defaultHearbeatCheckInterval,
+		HeartbeatFailReportInterval: defaultHearbeatFailReportInterval,
+		KafkaReconnectRetries:       defaultKafkaReconnectRetries,
+		CurrentReplica:              defaultCurrentReplica,
+		TotalReplicas:               defaultTotalReplicas,
+	}
+	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 ONU 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.DurationVar(&(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("Acceptance of incremental EVTOCD configuration")
+	flag.BoolVar(&(so.AccIncrEvto), "accept_incr_evto", defaultAccIncrEvto, 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 retries to connect to Kafka.")
+	flag.IntVar(&(so.KafkaReconnectRetries), "kafka_reconnect_retries", defaultKafkaReconnectRetries, help)
+
+	help = "Replica number of this particular instance (default: %s)"
+	flag.IntVar(&(so.CurrentReplica), "current_replica", defaultCurrentReplica, help)
+
+	help = "Total number of instances for this adapter"
+	flag.IntVar(&(so.TotalReplicas), "total_replica", defaultTotalReplicas, help)
+
+	flag.Parse()
+	containerName := getContainerInfo()
+	if len(containerName) > 0 {
+		so.InstanceID = containerName
+	}
+
+}
+
+func getContainerInfo() string {
+	return os.Getenv("HOSTNAME")
+}
diff --git a/internal/pkg/onuadaptercore/common.go b/internal/pkg/onuadaptercore/common.go
new file mode 100644
index 0000000..3616281
--- /dev/null
+++ b/internal/pkg/onuadaptercore/common.go
@@ -0,0 +1,32 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+var logger log.Logger
+
+func init() {
+	var err error
+	logger, err = log.AddPackage(log.JSON, log.ErrorLevel, log.Fields{"pkg": "adaptercoreonu"})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
new file mode 100644
index 0000000..9d00d5a
--- /dev/null
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -0,0 +1,1865 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"strconv"
+	"sync"
+	"time"
+
+	"github.com/gogo/protobuf/proto"
+	"github.com/golang/protobuf/ptypes"
+	"github.com/looplab/fsm"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db"
+	flow "github.com/opencord/voltha-lib-go/v3/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	vc "github.com/opencord/voltha-protos/v3/go/common"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	"github.com/opencord/voltha-protos/v3/go/openflow_13"
+	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"
+)
+
+/*
+// Constants for number of retries and for timeout
+const (
+	MaxRetry       = 10
+	MaxTimeOutInMs = 500
+)
+*/
+
+const (
+	devEvDeviceInit       = "devEvDeviceInit"
+	devEvGrpcConnected    = "devEvGrpcConnected"
+	devEvGrpcDisconnected = "devEvGrpcDisconnected"
+	devEvDeviceUpInd      = "devEvDeviceUpInd"
+	devEvDeviceDownInd    = "devEvDeviceDownInd"
+)
+const (
+	devStNull      = "devStNull"
+	devStDown      = "devStDown"
+	devStInit      = "devStInit"
+	devStConnected = "devStConnected"
+	devStUp        = "devStUp"
+)
+
+//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go  - should be done more centrally
+const (
+	pon = voltha.EventSubCategory_PON
+	equipment = voltha.EventCategory_EQUIPMENT
+)
+
+const (
+	cEventObjectType = "ONU"
+)
+const (
+	cOnuActivatedEvent = "ONU_ACTIVATED"
+)
+
+//deviceHandler will interact with the ONU ? device.
+type deviceHandler struct {
+	deviceID         string
+	DeviceType       string
+	adminState       string
+	device           *voltha.Device
+	logicalDeviceID  string
+	ProxyAddressID   string
+	ProxyAddressType string
+	parentID         string
+	ponPortNumber    uint32
+
+	coreProxy    adapterif.CoreProxy
+	AdapterProxy adapterif.AdapterProxy
+	EventProxy   adapterif.EventProxy
+
+	pOpenOnuAc      *OpenONUAC
+	pDeviceStateFsm *fsm.FSM
+	deviceEntrySet  chan bool //channel for DeviceEntry set event
+	pOnuOmciDevice  *OnuDeviceEntry
+	pOnuTP          *onuUniTechProf
+	exitChannel     chan int
+	lockDevice      sync.RWMutex
+	pOnuIndication  *oop.OnuIndication
+	deviceReason    string
+	pLockStateFsm   *lockStateFsm
+	pUnlockStateFsm *lockStateFsm
+
+
+	stopCollector       chan bool
+	stopHeartbeatCheck  chan bool
+	activePorts         sync.Map
+	uniEntityMap        map[uint32]*onuUniPort
+	UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
+	reconciling         bool
+}
+
+//newDeviceHandler creates a new device handler
+func newDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *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.pOpenOnuAc = adapter
+	dh.exitChannel = make(chan int, 1)
+	dh.lockDevice = sync.RWMutex{}
+	dh.deviceEntrySet = make(chan bool, 1)
+	dh.stopCollector = make(chan bool, 2)
+	dh.stopHeartbeatCheck = make(chan bool, 2)
+	dh.activePorts = sync.Map{}
+	dh.uniEntityMap = make(map[uint32]*onuUniPort)
+	dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
+	dh.reconciling = false
+
+	dh.pDeviceStateFsm = fsm.NewFSM(
+		devStNull,
+		fsm.Events{
+			{Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
+			{Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
+			{Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
+			{Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
+			{Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
+		},
+		fsm.Callbacks{
+			"before_event":                      func(e *fsm.Event) { dh.logStateChange(e) },
+			("before_" + devEvDeviceInit):       func(e *fsm.Event) { dh.doStateInit(e) },
+			("after_" + devEvDeviceInit):        func(e *fsm.Event) { dh.postInit(e) },
+			("before_" + devEvGrpcConnected):    func(e *fsm.Event) { dh.doStateConnected(e) },
+			("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
+			("after_" + devEvGrpcDisconnected):  func(e *fsm.Event) { dh.postInit(e) },
+			("before_" + devEvDeviceUpInd):      func(e *fsm.Event) { dh.doStateUp(e) },
+			("before_" + devEvDeviceDownInd):    func(e *fsm.Event) { dh.doStateDown(e) },
+		},
+	)
+
+	return &dh
+}
+
+// start save the device to the data model
+func (dh *deviceHandler) start(ctx context.Context) {
+	logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
+	logger.Debug("device-handler-started")
+}
+
+/*
+// stop stops the device dh.  Not much to do for now
+func (dh *deviceHandler) stop(ctx context.Context) {
+	logger.Debug("stopping-device-handler")
+	dh.exitChannel <- 1
+}
+*/
+
+// ##########################################################################################
+// deviceHandler methods that implement the adapters interface requests ##### begin #########
+
+//adoptOrReconcileDevice adopts the OLT device
+func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
+	logger.Debugw("Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
+
+	logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
+	if dh.pDeviceStateFsm.Is(devStNull) {
+		if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
+			logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
+		}
+		logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
+	} else {
+		logger.Debugw("AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
+	}
+
+}
+
+func (dh *deviceHandler) processInterAdapterOMCIReqMessage(msg *ic.InterAdapterMessage) error {
+	msgBody := msg.GetBody()
+	omciMsg := &ic.InterAdapterOmciMessage{}
+	if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
+		logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
+			"device-id": dh.deviceID, "error": err})
+		return err
+	}
+
+	logger.Debugw("inter-adapter-recv-omci", log.Fields{
+		"device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
+	pDevEntry := dh.getOnuDeviceEntry(true)
+	if pDevEntry != nil {
+		return pDevEntry.PDevOmciCC.receiveMessage(context.TODO(), omciMsg.Message)
+	}
+	logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
+	return errors.New("no valid OnuDevice")
+}
+
+func (dh *deviceHandler) processInterAdapterONUIndReqMessage(msg *ic.InterAdapterMessage) error {
+	msgBody := msg.GetBody()
+	onuIndication := &oop.OnuIndication{}
+	if err := ptypes.UnmarshalAny(msgBody, onuIndication); err != nil {
+		logger.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{
+			"device-id": dh.deviceID, "error": err})
+		return err
+	}
+
+	onuOperstate := onuIndication.GetOperState()
+	logger.Debugw("inter-adapter-recv-onu-ind", log.Fields{"OnuId": onuIndication.GetOnuId(),
+		"AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
+		"SNR": onuIndication.GetSerialNumber()})
+
+	if onuOperstate == "up" {
+		_ = dh.createInterface(onuIndication)
+	} else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
+		_ = dh.updateInterface(onuIndication)
+	} else {
+		logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
+		return errors.New("invalidOperState")
+	}
+	return nil
+}
+
+func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
+	msg *ic.InterAdapterMessage) error {
+	if dh.pOnuTP == nil {
+		//should normally not happen ...
+		logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
+			log.Fields{"device-id": dh.deviceID})
+		return errors.New("techProfile DLMsg request while onuTechProf instance not setup")
+	}
+	if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock") {
+		// I've seen cases for this request, where the device was already stopped
+		logger.Warnw("TechProf stopped: device-unreachable", log.Fields{"device-id": dh.deviceID})
+		return errors.New("device-unreachable")
+	}
+
+	msgBody := msg.GetBody()
+	techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
+	if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
+		logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
+			"device-id": dh.deviceID, "error": err})
+		return err
+	}
+
+	dh.pOnuTP.lockTpProcMutex()
+	if bTpModify := dh.pOnuTP.updateOnuUniTpPath(techProfMsg.UniId, techProfMsg.Path); bTpModify {
+		//	if there has been some change for some uni TechProfilePath
+		//in order to allow concurrent calls to other dh instances we do not wait for execution here
+		//but doing so we can not indicate problems to the caller (who does what with that then?)
+		//by now we just assume straightforward successful execution
+		//TODO!!! Generally: In this scheme it would be good to have some means to indicate
+		//  possible problems to the caller later autonomously
+
+		// deadline context to ensure completion of background routines waited for
+		//20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
+		deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
+		dctx, cancel := context.WithDeadline(context.Background(), deadline)
+
+		dh.pOnuTP.resetProcessingErrorIndication()
+		var wg sync.WaitGroup
+		wg.Add(2) // for the 2 go routines to finish
+		// attention: deadline completion check and wg.Done is to be done in both routines
+		go dh.pOnuTP.configureUniTp(dctx, uint8(techProfMsg.UniId), techProfMsg.Path, &wg)
+		go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
+		//the wait.. function is responsible for tpProcMutex.Unlock()
+		err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //wait for background process to finish and collect their result
+		return err
+	}
+	dh.pOnuTP.unlockTpProcMutex()
+	return nil
+}
+
+func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
+	msg *ic.InterAdapterMessage) error {
+
+	if dh.pOnuTP == nil {
+		//should normally not happen ...
+		logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
+			log.Fields{"device-id": dh.deviceID})
+		return errors.New("techProfile DelGem request while onuTechProf instance not setup")
+	}
+
+	msgBody := msg.GetBody()
+	delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
+	if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
+		logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
+			"device-id": dh.deviceID, "error": err})
+		return err
+	}
+
+	dh.pOnuTP.lockTpProcMutex()
+
+	deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
+	dctx, cancel := context.WithDeadline(context.Background(), deadline)
+
+	dh.pOnuTP.resetProcessingErrorIndication()
+	var wg sync.WaitGroup
+	wg.Add(1) // for the 1 go routine to finish
+	go dh.pOnuTP.deleteTpResource(dctx, delGemPortMsg.UniId, delGemPortMsg.TpPath,
+		cResourceGemPort, delGemPortMsg.GemPortId, &wg)
+	err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
+	return err
+}
+
+func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
+	msg *ic.InterAdapterMessage) error {
+	if dh.pOnuTP == nil {
+		//should normally not happen ...
+		logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
+			log.Fields{"device-id": dh.deviceID})
+		return errors.New("techProfile DelTcont request while onuTechProf instance not setup")
+	}
+
+	msgBody := msg.GetBody()
+	delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
+	if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
+		logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
+			"device-id": dh.deviceID, "error": err})
+		return err
+	}
+
+	dh.pOnuTP.lockTpProcMutex()
+	if bTpModify := dh.pOnuTP.updateOnuUniTpPath(delTcontMsg.UniId, ""); bTpModify {
+		// deadline context to ensure completion of background routines waited for
+		deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
+		dctx, cancel := context.WithDeadline(context.Background(), deadline)
+
+		dh.pOnuTP.resetProcessingErrorIndication()
+		var wg sync.WaitGroup
+		wg.Add(2) // for the 2 go routines to finish
+		go dh.pOnuTP.deleteTpResource(dctx, delTcontMsg.UniId, delTcontMsg.TpPath,
+			cResourceTcont, delTcontMsg.AllocId, &wg)
+		// Removal of the tcont/alloc id mapping represents the removal of the tech profile
+		go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
+		//the wait.. function is responsible for tpProcMutex.Unlock()
+		err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
+		return err
+	}
+	dh.pOnuTP.unlockTpProcMutex()
+	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 {
+	msgID := msg.Header.Id
+	msgType := msg.Header.Type
+	fromTopic := msg.Header.FromTopic
+	toTopic := msg.Header.ToTopic
+	toDeviceID := msg.Header.ToDeviceId
+	proxyDeviceID := msg.Header.ProxyDeviceId
+	logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
+		"fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
+
+	switch msgType {
+	case ic.InterAdapterMessageType_OMCI_REQUEST:
+		{
+			return dh.processInterAdapterOMCIReqMessage(msg)
+		}
+	case ic.InterAdapterMessageType_ONU_IND_REQUEST:
+		{
+			return dh.processInterAdapterONUIndReqMessage(msg)
+		}
+	case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
+		{
+			return dh.processInterAdapterTechProfileDownloadReqMessage(msg)
+		}
+	case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
+		{
+			return dh.processInterAdapterDeleteGemPortReqMessage(msg)
+
+		}
+	case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
+		{
+			return dh.processInterAdapterDeleteTcontReqMessage(msg)
+		}
+	default:
+		{
+			logger.Errorw("inter-adapter-unhandled-type", log.Fields{
+				"device-id": dh.deviceID, "msgType": msg.Header.Type})
+			return errors.New("unimplemented")
+		}
+	}
+}
+
+//FlowUpdateIncremental removes and/or adds the flow changes on a given device
+func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
+	apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
+
+	if apOfFlowChanges.ToRemove != nil {
+		for _, flowItem := range apOfFlowChanges.ToRemove.Items {
+			logger.Debugw("incremental flow item remove", log.Fields{"deviceId": dh.deviceID,
+				"Item": flowItem})
+		}
+	}
+	if apOfFlowChanges.ToAdd != nil {
+		for _, flowItem := range apOfFlowChanges.ToAdd.Items {
+			if flowItem.GetCookie() == 0 {
+				logger.Debugw("incremental flow add - no cookie - ignore", log.Fields{
+					"deviceId": dh.deviceID})
+				continue
+			}
+			flowInPort := flow.GetInPort(flowItem)
+			if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
+				logger.Errorw("flow inPort invalid", log.Fields{"deviceID": dh.deviceID})
+				return errors.New("flow inPort invalid")
+			} else if flowInPort == dh.ponPortNumber {
+				//this is some downstream flow
+				logger.Debugw("incremental flow ignore downstream", log.Fields{
+					"deviceId": dh.deviceID, "inPort": flowInPort})
+				continue
+			} else {
+				// this is the relevant upstream flow
+				var loUniPort *onuUniPort
+				if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
+					loUniPort = uniPort
+				} else {
+					logger.Errorw("flow inPort not found in UniPorts",
+						log.Fields{"deviceID": dh.deviceID, "inPort": flowInPort})
+					return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
+				}
+				flowOutPort := flow.GetOutPort(flowItem)
+				logger.Debugw("incremental flow-add port indications", log.Fields{
+					"deviceId": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
+					"uniPortName": loUniPort.name})
+				err := dh.addFlowItemToUniPort(flowItem, loUniPort)
+				//abort processing in error case
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
+// TODO!!! Clarify usage of this method, it is for sure not used within ONOS (OLT) device disable
+//         maybe it is obsolete by now
+func (dh *deviceHandler) disableDevice(device *voltha.Device) {
+	logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
+
+	if dh.deviceReason != "omci-admin-lock" {
+		// disable UNI ports/ONU
+		// *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
+		//     here the result of the processing is not checked (trusted in background) *****
+		if dh.pLockStateFsm == nil {
+			dh.createUniLockFsm(true, UniAdminStateDone)
+		} else { //LockStateFSM already init
+			dh.pLockStateFsm.setSuccessEvent(UniAdminStateDone)
+			dh.runUniLockFsm(true)
+		}
+
+		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
+		}
+		dh.deviceReason = "omci-admin-lock"
+		//200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
+		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
+			voltha.OperStatus_UNKNOWN); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
+		}
+
+		// update json file
+		// onustat := &OnuStatus{
+		// 	Id:           dh.deviceID,
+		// 	AdminState:   vc.AdminState_Types_name[int32(dh.device.AdminState)],
+		// 	OpeState:     vc.OperStatus_Types_name[int32(dh.device.OperStatus)],
+		// 	ConnectState: vc.ConnectStatus_Types_name[int32(dh.device.ConnectStatus)],
+		// 	MacAddress:   dh.device.MacAddress,
+		// }
+		// logger.Debugw("UpdateOnu", log.Fields{"Id": dh.deviceID})
+		// err := UpdateOnu(onustat)
+		// logger.Debugw("UpdateOnu", log.Fields{"err": err})
+	}
+}
+
+//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
+// TODO!!! Clarify usage of this method, compare above DisableDevice, usage may clarify resulting states
+//         maybe it is obsolete by now
+func (dh *deviceHandler) reEnableDevice(device *voltha.Device) {
+	logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
+
+	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
+		voltha.OperStatus_ACTIVE); err != nil {
+		//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+		logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
+	}
+
+	if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
+		//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+		logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
+	}
+	dh.deviceReason = "initial-mib-downloaded"
+
+
+	if dh.pUnlockStateFsm == nil {
+		dh.createUniLockFsm(false, UniAdminStateDone)
+	} else { //UnlockStateFSM already init
+		dh.pUnlockStateFsm.setSuccessEvent(UniAdminStateDone)
+		dh.runUniLockFsm(false)
+	}
+}
+
+func (dh *deviceHandler) reconcileDeviceOnuInd() {
+	logger.Debugw("reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
+
+	if err := dh.pOnuTP.restoreFromOnuTpPathKvStore(context.TODO()); err != nil {
+		logger.Errorw("reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
+		dh.reconciling = false
+		return
+	}
+	var onuIndication oop.OnuIndication
+	onuIndication.IntfId = dh.pOnuTP.sOnuPersistentData.PersIntfID
+	onuIndication.OnuId = dh.pOnuTP.sOnuPersistentData.PersOnuID
+	onuIndication.OperState = dh.pOnuTP.sOnuPersistentData.PersOperState
+	onuIndication.AdminState = dh.pOnuTP.sOnuPersistentData.PersAdminState
+	_ = dh.createInterface(&onuIndication)
+}
+
+func (dh *deviceHandler) reconcileDeviceTechProf() {
+	logger.Debugw("reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
+
+	dh.pOnuTP.lockTpProcMutex()
+	for _, uniData := range dh.pOnuTP.sOnuPersistentData.PersUniTpPath {
+		//In order to allow concurrent calls to other dh instances we do not wait for execution here
+		//but doing so we can not indicate problems to the caller (who does what with that then?)
+		//by now we just assume straightforward successful execution
+		//TODO!!! Generally: In this scheme it would be good to have some means to indicate
+		//  possible problems to the caller later autonomously
+
+		// deadline context to ensure completion of background routines waited for
+		//20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
+		deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
+		dctx, cancel := context.WithDeadline(context.Background(), deadline)
+
+		dh.pOnuTP.resetProcessingErrorIndication()
+		var wg sync.WaitGroup
+		wg.Add(1) // for the 1 go routines to finish
+		// attention: deadline completion check and wg.Done is to be done in both routines
+		go dh.pOnuTP.configureUniTp(dctx, uint8(uniData.PersUniID), uniData.PersTpPath, &wg)
+		//the wait.. function is responsible for tpProcMutex.Unlock()
+		_ = dh.pOnuTP.waitForTpCompletion(cancel, &wg) //wait for background process to finish and collect their result
+		return
+	}
+	dh.pOnuTP.unlockTpProcMutex()
+	dh.reconciling = false
+}
+
+func (dh *deviceHandler) deleteDevice(device *voltha.Device) error {
+	logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
+	if err := dh.pOnuTP.deleteOnuTpPathKvStore(context.TODO()); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (dh *deviceHandler) rebootDevice(device *voltha.Device) error {
+	logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
+	if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
+		logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
+		return errors.New("device-unreachable")
+	}
+	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
+		voltha.OperStatus_DISCOVERED); err != nil {
+		//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+		logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
+		return err
+	}
+	if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting-onu"); err != nil {
+		//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+		logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
+		return err
+	}
+	dh.deviceReason = "rebooting-onu"
+
+	if err := dh.sendMsgToOlt(context.TODO(), "reboot", nil); err != nil {
+		logger.Debugw("error", log.Fields{"error": err})
+	}
+
+	return nil
+}
+
+//  deviceHandler methods that implement the adapters interface requests## end #########
+// #####################################################################################
+
+// ################  to be updated acc. needs of ONU Device ########################
+// deviceHandler StateMachine related state transition methods ##### begin #########
+
+func (dh *deviceHandler) logStateChange(e *fsm.Event) {
+	logger.Debugw("Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
+}
+
+// doStateInit provides the device update to the core
+func (dh *deviceHandler) doStateInit(e *fsm.Event) {
+
+	logger.Debug("doStateInit-started")
+	var err error
+
+	dh.device.Root = false
+	dh.device.Vendor = "OpenONU"
+	dh.device.Model = "go"
+	dh.device.Reason = "activating-onu"
+	dh.deviceReason = "activating-onu"
+
+	dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
+
+	if !dh.reconciling {
+		_ = dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
+	} else {
+		logger.Debugw("reconciling - don't notify core about DeviceUpdate",
+			log.Fields{"device-id": dh.deviceID})
+	}
+
+	dh.parentID = dh.device.ParentId
+	dh.ponPortNumber = dh.device.ParentPortNo
+
+	dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
+	dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
+	logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
+		"proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
+		"ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
+
+	/*
+		self._pon = PonPort.create(self, self._pon_port_number)
+		self._pon.add_peer(self.parent_id, self._pon_port_number)
+		self.logger.debug('adding-pon-port-to-agent',
+				   type=self._pon.get_port().type,
+				   admin_state=self._pon.get_port().admin_state,
+				   oper_status=self._pon.get_port().oper_status,
+				   )
+	*/
+	if !dh.reconciling {
+		logger.Debugw("adding-pon-port", log.Fields{"deviceID": dh.deviceID, "ponPortNo": dh.ponPortNumber})
+		var ponPortNo uint32 = 1
+		if dh.ponPortNumber != 0 {
+			ponPortNo = dh.ponPortNumber
+		}
+
+		pPonPort := &voltha.Port{
+			PortNo: ponPortNo,
+			//Label:      fmt.Sprintf("pon-%d", ponPortNo),
+			Label:      "PON port",
+			Type:       voltha.Port_PON_ONU,
+			OperStatus: voltha.OperStatus_ACTIVE,
+			Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device  is OLT
+				PortNo: ponPortNo}}, // Peer port is parent's port number
+		}
+		if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
+			logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
+			e.Cancel(err)
+			return
+		}
+	} else {
+		logger.Debugw("reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
+	}
+	logger.Debug("doStateInit-done")
+}
+
+// postInit setups the DeviceEntry for the conerned device
+func (dh *deviceHandler) postInit(e *fsm.Event) {
+
+	logger.Debug("postInit-started")
+	var err error
+	/*
+		dh.Client = oop.NewOpenoltClient(dh.clientCon)
+		dh.pTransitionMap.Handle(ctx, GrpcConnected)
+		return nil
+	*/
+	if err = dh.addOnuDeviceEntry(context.TODO()); err != nil {
+		logger.Fatalf("Device FSM: addOnuDeviceEntry-failed-%s", err)
+		e.Cancel(err)
+		return
+	}
+
+	if dh.reconciling {
+		go dh.reconcileDeviceOnuInd()
+		// reconcilement will be continued after mib download is done
+	}
+	/*
+			############################################################################
+			# Setup Alarm handler
+			self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
+										device.serial_number)
+			############################################################################
+			# Setup PM configuration for this device
+			# Pass in ONU specific options
+			kwargs = {
+				OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
+				'heartbeat': self.heartbeat,
+				OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
+			}
+			self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
+			self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
+										   self.logical_device_id, device.serial_number,
+										   grouped=True, freq_override=False, **kwargs)
+			pm_config = self._pm_metrics.make_proto()
+			self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
+			self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
+			yield self.core_proxy.device_pm_config_update(pm_config, init=True)
+
+			# Note, ONU ID and UNI intf set in add_uni_port method
+			self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
+																	  ani_ports=[self._pon])
+
+			# Code to Run OMCI Test Action
+			kwargs_omci_test_action = {
+				OmciTestRequest.DEFAULT_FREQUENCY_KEY:
+					OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
+			}
+			serial_number = device.serial_number
+			self._test_request = OmciTestRequest(self.core_proxy,
+										   self.omci_agent, self.device_id,
+										   AniG, serial_number,
+										   self.logical_device_id,
+										   exclusive=False,
+										   **kwargs_omci_test_action)
+
+			self.enabled = True
+		else:
+			self.logger.info('onu-already-activated')
+	*/
+	logger.Debug("postInit-done")
+}
+
+// doStateConnected get the device info and update to voltha core
+// for comparison of the original method (not that easy to uncomment): compare here:
+//  voltha-openolt-adapter/adaptercore/device_handler.go
+//  -> this one obviously initiates all communication interfaces of the device ...?
+func (dh *deviceHandler) doStateConnected(e *fsm.Event) {
+
+	logger.Debug("doStateConnected-started")
+	err := errors.New("device FSM: function not implemented yet")
+	e.Cancel(err)
+	logger.Debug("doStateConnected-done")
+}
+
+// doStateUp handle the onu up indication and update to voltha core
+func (dh *deviceHandler) doStateUp(e *fsm.Event) {
+
+	logger.Debug("doStateUp-started")
+	err := errors.New("device FSM: function not implemented yet")
+	e.Cancel(err)
+	logger.Debug("doStateUp-done")
+
+	/*
+		// 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 {
+			logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
+			return err
+		}
+		return nil
+	*/
+}
+
+// doStateDown handle the onu down indication
+func (dh *deviceHandler) doStateDown(e *fsm.Event) {
+
+	logger.Debug("doStateDown-started")
+	var err error
+
+	device := dh.device
+	if device == nil {
+		/*TODO: needs to handle error scenarios */
+		logger.Error("Failed to fetch handler device")
+		e.Cancel(err)
+		return
+	}
+
+	cloned := proto.Clone(device).(*voltha.Device)
+	logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
+	/*
+		// Update the all ports state on that device to disable
+		if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
+			logger.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
+			return er
+		}
+
+		//Update the device oper state and connection status
+		cloned.OperStatus = voltha.OperStatus_UNKNOWN
+		cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
+		dh.device = cloned
+
+		if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
+			logger.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
+			return er
+		}
+
+		//get the child device for the parent device
+		onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
+		if err != nil {
+			logger.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
+			return err
+		}
+		for _, onuDevice := range onuDevices.Items {
+
+			// Update onu state as down in onu adapter
+			onuInd := oop.OnuIndication{}
+			onuInd.OperState = "down"
+			er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
+				"openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
+			if er != nil {
+				logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
+					"From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
+				//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{}
+		logger.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
+		return nil
+	*/
+	err = errors.New("device FSM: function not implemented yet")
+	e.Cancel(err)
+	logger.Debug("doStateDown-done")
+}
+
+// deviceHandler StateMachine related state transition methods ##### end #########
+// #################################################################################
+
+// ###################################################
+// deviceHandler utility methods ##### begin #########
+
+//getOnuDeviceEntry getsthe  ONU device entry and may wait until its value is defined
+func (dh *deviceHandler) getOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
+	dh.lockDevice.RLock()
+	pOnuDeviceEntry := dh.pOnuOmciDevice
+	if aWait && pOnuDeviceEntry == nil {
+		//keep the read sema short to allow for subsequent write
+		dh.lockDevice.RUnlock()
+		logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
+		// based on concurrent processing the deviceEntry setup may not yet be finished at his point
+		// so it might be needed to wait here for that event with some timeout
+		select {
+		case <-time.After(60 * time.Second): //timer may be discussed ...
+			logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
+			return nil
+		case <-dh.deviceEntrySet:
+			logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
+			// if written now, we can return the written value without sema
+			return dh.pOnuOmciDevice
+		}
+	}
+	dh.lockDevice.RUnlock()
+	return pOnuDeviceEntry
+}
+
+//setOnuDeviceEntry sets the ONU device entry within the handler
+func (dh *deviceHandler) setOnuDeviceEntry(
+	apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf) {
+	dh.lockDevice.Lock()
+	defer dh.lockDevice.Unlock()
+	dh.pOnuOmciDevice = apDeviceEntry
+	dh.pOnuTP = apOnuTp
+}
+
+//addOnuDeviceEntry creates a new ONU device or returns the existing
+func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
+	logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
+
+	deviceEntry := dh.getOnuDeviceEntry(false)
+	if deviceEntry == nil {
+		/* costum_me_map in python code seems always to be None,
+		   we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
+		/* also no 'clock' argument - usage open ...*/
+		/* and no alarm_db yet (oo.alarm_db)  */
+		deviceEntry = newOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
+			dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
+			dh, dh.coreProxy, dh.AdapterProxy,
+			dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
+		onuTechProfProc := newOnuUniTechProf(ctx, dh.deviceID, dh)
+		//error treatment possible //TODO!!!
+		dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc)
+		// fire deviceEntry ready event to spread to possibly waiting processing
+		dh.deviceEntrySet <- true
+
+		//dh.sendMsgToOlt(ctx, "adopt", nil)
+		// // update json file
+		// onustat := &OnuStatus{
+		// 	Id:           dh.deviceID,
+		// 	AdminState:   vc.AdminState_Types_name[int32(dh.device.AdminState)],
+		// 	OpeState:     vc.OperStatus_Types_name[int32(dh.device.OperStatus)],
+		// 	ConnectState: vc.ConnectStatus_Types_name[int32(dh.device.ConnectStatus)],
+		// 	MacAddress:   dh.device.MacAddress,
+		// }
+		// logger.Debugw("AddOnu", log.Fields{"Id": onustat.Id, "Admin": onustat.AdminState, "Ope": onustat.OpeState, "Con": onustat.ConnectState, "Mac": onustat.MacAddress})
+		// err := AddOnu(onustat)
+		// logger.Debugw("AddOnu", log.Fields{"err": err})
+		// //
+		// go WatchStatus(ctx, dh.coreProxy)
+
+		// dh.device.Root = true
+		// dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
+
+		logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
+	} else {
+		logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
+	}
+	return nil
+}
+
+// doStateInit provides the device update to the core
+func (dh *deviceHandler) createInterface(onuind *oop.OnuIndication) error {
+	logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
+		"OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
+
+	dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
+
+	if !dh.reconciling {
+		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
+			voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
+		}
+	} else {
+		logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
+			log.Fields{"device-id": dh.deviceID})
+	}
+	/*
+			device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
+		    if err != nil || device == nil {
+					//TODO: needs to handle error scenarios
+				logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
+				return errors.New("Voltha Device not found")
+			}
+	*/
+
+	pDevEntry := dh.getOnuDeviceEntry(true)
+	if pDevEntry != nil {
+		if err := pDevEntry.start(context.TODO()); err != nil {
+			return err
+		}
+	} else {
+		logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
+		return errors.New("no valid OnuDevice")
+	}
+	if !dh.reconciling {
+		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
+		}
+	} else {
+		logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to starting-openomci",
+			log.Fields{"device-id": dh.deviceID})
+	}
+	dh.deviceReason = "starting-openomci"
+
+	/* this might be a good time for Omci Verify message?  */
+	verifyExec := make(chan bool)
+	omciVerify := newOmciTestRequest(context.TODO(),
+		dh.device.Id, pDevEntry.PDevOmciCC,
+		true, true) //eclusive and allowFailure (anyway not yet checked)
+	omciVerify.performOmciTest(context.TODO(), verifyExec)
+
+	/* 	give the handler some time here to wait for the OMCi verification result
+	after Timeout start and try MibUpload FSM anyway
+	(to prevent stopping on just not supported OMCI verification from ONU) */
+	select {
+	case <-time.After(2 * time.Second):
+		logger.Warn("omci start-verification timed out (continue normal)")
+	case testresult := <-verifyExec:
+		logger.Infow("Omci start verification done", log.Fields{"result": testresult})
+	}
+
+	/* In py code it looks earlier (on activate ..)
+			# Code to Run OMCI Test Action
+			kwargs_omci_test_action = {
+				OmciTestRequest.DEFAULT_FREQUENCY_KEY:
+					OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
+			}
+			serial_number = device.serial_number
+			self._test_request = OmciTestRequest(self.core_proxy,
+											self.omci_agent, self.device_id,
+											AniG, serial_number,
+											self.logical_device_id,
+											exclusive=False,
+											**kwargs_omci_test_action)
+	...
+	                    # Start test requests after a brief pause
+	                    if not self._test_request_started:
+	                        self._test_request_started = True
+	                        tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
+	                        reactor.callLater(tststart, self._test_request.start_collector)
+
+	*/
+	/* which is then: in omci_test_request.py : */
+	/*
+	   def start_collector(self, callback=None):
+	       """
+	               Start the collection loop for an adapter if the frequency > 0
+
+	               :param callback: (callable) Function to call to collect PM data
+	       """
+	       self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
+	       if callback is None:
+	           callback = self.perform_test_omci
+
+	       if self.lc is None:
+	           self.lc = LoopingCall(callback)
+
+	       if self.default_freq > 0:
+	           self.lc.start(interval=self.default_freq / 10)
+
+	   def perform_test_omci(self):
+	       """
+	       Perform the initial test request
+	       """
+	       ani_g_entities = self._device.configuration.ani_g_entities
+	       ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
+	                                                     is not None else None
+	       self._entity_id = ani_g_entities_ids[0]
+	       self.logger.info('perform-test', entity_class=self._entity_class,
+	                     entity_id=self._entity_id)
+	       try:
+	           frame = MEFrame(self._entity_class, self._entity_id, []).test()
+	           result = yield self._device.omci_cc.send(frame)
+	           if not result.fields['omci_message'].fields['success_code']:
+	               self.logger.info('Self-Test Submitted Successfully',
+	                             code=result.fields[
+	                                 'omci_message'].fields['success_code'])
+	           else:
+	               raise TestFailure('Test Failure: {}'.format(
+	                   result.fields['omci_message'].fields['success_code']))
+	       except TimeoutError as e:
+	           self.deferred.errback(failure.Failure(e))
+
+	       except Exception as e:
+	           self.logger.exception('perform-test-Error', e=e,
+	                              class_id=self._entity_class,
+	                              entity_id=self._entity_id)
+	           self.deferred.errback(failure.Failure(e))
+
+	*/
+
+
+	/* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
+	 * 	 within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
+	 *   as further OltAdapter processing may rely on the deviceReason event 'MibUploadDone' as a result of the FSM processing
+	 *   otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
+	 */
+	pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
+	if pMibUlFsm != nil {
+		if pMibUlFsm.Is(ulStDisabled) {
+			if err := pMibUlFsm.Event(ulEvStart); err != nil {
+				logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"err": err})
+				return errors.New("can't go to state starting")
+			}
+			logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
+			//Determine ONU status and start/re-start MIB Synchronization tasks
+			//Determine if this ONU has ever synchronized
+			if true { //TODO: insert valid check
+				if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
+					logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"err": err})
+					return errors.New("can't go to state resetting_mib")
+				}
+			} else {
+				if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
+					logger.Errorw("MibSyncFsm: Can't go to state examine_mds", log.Fields{"err": err})
+					return errors.New("can't go to examine_mds")
+				}
+				logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
+				//Examine the MIB Data Sync
+				// callbacks to be handled:
+				// Event(ulEvSuccess)
+				// Event(ulEvTimeout)
+				// Event(ulEvMismatch)
+			}
+		} else {
+			logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current())})
+			return errors.New("wrong state of MibSyncFsm")
+		}
+	} else {
+		logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
+		return errors.New("cannot execut MibSync")
+	}
+	return nil
+}
+
+func (dh *deviceHandler) updateInterface(onuind *oop.OnuIndication) error {
+	if dh.deviceReason != "stopping-openomci" {
+		logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
+		//stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
+		pDevEntry := dh.getOnuDeviceEntry(false)
+		if pDevEntry == nil {
+			logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
+			return errors.New("no valid OnuDevice")
+		}
+
+		switch dh.deviceReason {
+		case "starting-openomci":
+			{ //MIBSync FSM may run
+				pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
+				if pMibUlFsm != nil {
+					_ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
+				}
+			}
+		case "discovery-mibsync-complete":
+			{ //MibDownload may run
+				pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
+				if pMibDlFsm != nil {
+					_ = pMibDlFsm.Event(dlEvReset)
+				}
+			}
+		default:
+			{
+				//port lock/unlock FSM's may be active
+				if dh.pUnlockStateFsm != nil {
+					_ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
+				}
+				if dh.pLockStateFsm != nil {
+					_ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
+				}
+				//techProfile related PonAniConfigFsm FSM may be active
+				// maybe encapsulated as OnuTP method - perhaps later in context of module splitting
+				if dh.pOnuTP.pAniConfigFsm != nil {
+					_ = dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+				}
+				for _, uniPort := range dh.uniEntityMap {
+					//reset the TechProfileConfig Done state for all (active) UNI's
+					dh.pOnuTP.setConfigDone(uniPort.uniID, false)
+					// reset the possibly existing VlanConfigFsm
+					if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
+						//VlanFilterFsm exists and was already started
+						pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
+						if pVlanFilterStatemachine != nil {
+							_ = pVlanFilterStatemachine.Event(vlanEvReset)
+						}
+					}
+				}
+			}
+			//TODO!!! care about PM/Alarm processing once started
+		}
+		//TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
+		//  (mainly the still separate 'Event states')
+		//  so it is questionable, how this is resolved after some possible re-enable
+		//  assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
+
+		//stop/remove(?) the device entry
+		_ = pDevEntry.stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
+
+		//TODO!!! remove existing traffic profiles
+		/* from py code, if TP's exist, remove them - not yet implemented
+		self._tp = dict()
+		# Let TP download happen again
+		for uni_id in self._tp_service_specific_task:
+			self._tp_service_specific_task[uni_id].clear()
+		for uni_id in self._tech_profile_download_done:
+			self._tech_profile_download_done[uni_id].clear()
+		*/
+
+		dh.disableUniPortStateUpdate()
+
+		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
+				log.Fields{"device-id": dh.deviceID, "error": err})
+			// abort: system behavior is just unstable ...
+			return err
+		}
+		dh.deviceReason = "stopping-openomci"
+
+		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
+			voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-device-state unreachable-discovered",
+				log.Fields{"device-id": dh.deviceID, "error": err})
+			// abort: system behavior is just unstable ...
+			return err
+		}
+	} else {
+		logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
+	}
+	return nil
+}
+
+func (dh *deviceHandler) processMibDatabaseSyncEvent(devEvent OnuDeviceEvent) {
+	logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
+	if !dh.reconciling {
+		//initiate DevStateUpdate
+		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
+				"device-id": dh.deviceID, "error": err})
+		} else {
+			logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
+		}
+	} else {
+		logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to mibsync-complete",
+			log.Fields{"device-id": dh.deviceID})
+	}
+	dh.deviceReason = "discovery-mibsync-complete"
+
+	i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
+	pDevEntry := dh.getOnuDeviceEntry(false)
+	if unigInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
+		for _, mgmtEntityID := range unigInstKeys {
+			logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
+				"device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityID})
+			dh.addUniPort(mgmtEntityID, i, uniPPTP)
+			i++
+		}
+	} else {
+		logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
+	}
+	if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
+		for _, mgmtEntityID := range veipInstKeys {
+			logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
+				"device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
+			dh.addUniPort(mgmtEntityID, i, uniVEIP)
+			i++
+		}
+	} else {
+		logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
+	}
+	if i == 0 {
+		logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
+	}
+
+	/* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
+	 *  left the code here as comment in case such processing should prove needed unexpectedly
+			// Init Uni Ports to Admin locked state
+			// maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
+			// *** should generate UniLockStateDone event *****
+			if dh.pLockStateFsm == nil {
+				dh.createUniLockFsm(true, UniLockStateDone)
+			} else { //LockStateFSM already init
+				dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
+				dh.runUniLockFsm(true)
+			}
+		}
+	case UniLockStateDone:
+		{
+			logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
+	* lockState processing commented out
+	*/
+	/*  Mib download procedure -
+	***** should run over 'downloaded' state and generate MibDownloadDone event *****
+	 */
+	pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
+	if pMibDlFsm != nil {
+		if pMibDlFsm.Is(dlStDisabled) {
+			if err := pMibDlFsm.Event(dlEvStart); err != nil {
+				logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"err": err})
+				// maybe try a FSM reset and then again ... - TODO!!!
+			} else {
+				logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
+				// maybe use more specific states here for the specific download steps ...
+				if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
+					logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"err": err})
+				} else {
+					logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
+					//Begin MIB data download (running autonomously)
+				}
+			}
+		} else {
+			logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current())})
+			// maybe try a FSM reset and then again ... - TODO!!!
+		}
+		/***** Mib download started */
+	} else {
+		logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
+	}
+}
+
+func (dh *deviceHandler) processMibDownloadDoneEvent(devEvent OnuDeviceEvent) {
+	logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
+	if !dh.reconciling {
+		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
+			voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
+		} else {
+			logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
+		}
+	} else {
+		logger.Debugw("reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
+			log.Fields{"device-id": dh.deviceID})
+	}
+	if !dh.reconciling {
+		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
+				log.Fields{"device-id": dh.deviceID, "error": err})
+		} else {
+			logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
+		}
+	} else {
+		logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to initial-mib-downloaded",
+			log.Fields{"device-id": dh.deviceID})
+	}
+	dh.deviceReason = "initial-mib-downloaded"
+	if dh.pUnlockStateFsm == nil {
+		dh.createUniLockFsm(false, UniUnlockStateDone)
+	} else { //UnlockStateFSM already init
+		dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
+		dh.runUniLockFsm(false)
+	}
+}
+
+func (dh *deviceHandler) processUniUnlockStateDoneEvent(devEvent OnuDeviceEvent) {
+	go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
+
+	if !dh.reconciling {
+		logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
+		raisedTs := time.Now().UnixNano()
+		go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
+	} else {
+		logger.Debugw("reconciling - don't notify core that onu went to active but trigger tech profile config",
+			log.Fields{"device-id": dh.deviceID})
+		go dh.reconcileDeviceTechProf()
+		//TODO: further actions e.g. restore flows, metrics, ...
+	}
+}
+
+func (dh *deviceHandler) processOmciAniConfigDoneEvent(devEvent OnuDeviceEvent) {
+	logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
+	if dh.deviceReason != "tech-profile-config-download-success" {
+		// which may be the case from some previous actvity on another UNI Port of the ONU
+		if !dh.reconciling {
+			if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
+				//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+				logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
+					log.Fields{"device-id": dh.deviceID, "error": err})
+			} else {
+				logger.Infow("update dev reason to 'tech-profile-config-download-success'",
+					log.Fields{"device-id": dh.deviceID})
+			}
+		} else {
+			logger.Debugw("reconciling - don't notify core about DeviceReasonUpdate to tech-profile-config-download-success",
+				log.Fields{"device-id": dh.deviceID})
+		}
+		//set internal state anyway - as it was done
+		dh.deviceReason = "tech-profile-config-download-success"
+	}
+}
+
+func (dh *deviceHandler) processOmciVlanFilterDoneEvent(devEvent OnuDeviceEvent) {
+	logger.Debugw("OmciVlanFilterDone event received",
+		log.Fields{"device-id": dh.deviceID})
+
+	if dh.deviceReason != "omci-flows-pushed" {
+		// which may be the case from some previous actvity on another UNI Port of the ONU
+		// or even some previous flow add activity on the same port
+		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-flows-pushed"); err != nil {
+			logger.Errorw("error-DeviceReasonUpdate to 'omci-flows-pushed'",
+				log.Fields{"device-id": dh.deviceID, "error": err})
+		} else {
+			logger.Infow("updated dev reason to ''omci-flows-pushed'",
+				log.Fields{"device-id": dh.deviceID})
+		}
+		//set internal state anyway - as it was done
+		dh.deviceReason = "omci-flows-pushed"
+	}
+}
+
+//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
+func (dh *deviceHandler) deviceProcStatusUpdate(devEvent OnuDeviceEvent) {
+	switch devEvent {
+	case MibDatabaseSync:
+		{
+			dh.processMibDatabaseSyncEvent(devEvent)
+		}
+	case MibDownloadDone:
+		{
+			dh.processMibDownloadDoneEvent(devEvent)
+
+		}
+	case UniUnlockStateDone:
+		{
+			dh.processUniUnlockStateDoneEvent(devEvent)
+
+		}
+	case OmciAniConfigDone:
+		{
+			dh.processOmciAniConfigDoneEvent(devEvent)
+
+		}
+	case OmciVlanFilterDone:
+		{
+			dh.processOmciVlanFilterDoneEvent(devEvent)
+
+		}
+	default:
+		{
+			logger.Warnw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
+		}
+	} //switch
+}
+
+func (dh *deviceHandler) addUniPort(aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
+	uniNo := mkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
+		uint32(aUniID))
+	if _, present := dh.uniEntityMap[uniNo]; present {
+		logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
+	} else {
+		//with arguments aUniID, a_portNo, aPortType
+		pUniPort := newOnuUniPort(aUniID, uniNo, aUniInstNo, aPortType)
+		if pUniPort == nil {
+			logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
+		} else {
+			//store UniPort with the System-PortNumber key
+			dh.uniEntityMap[uniNo] = pUniPort
+			if !dh.reconciling {
+				// create announce the UniPort to the core as VOLTHA Port object
+				if err := pUniPort.createVolthaPort(dh); err == nil {
+					logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
+				} //error logging already within UniPort method
+			} else {
+				logger.Debugw("reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
+			}
+		}
+	}
+}
+
+// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
+func (dh *deviceHandler) enableUniPortStateUpdate() {
+
+
+	for uniNo, uniPort := range dh.uniEntityMap {
+		// only if this port is validated for operState transfer
+		if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
+			logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
+			uniPort.setOperState(vc.OperStatus_ACTIVE)
+			if !dh.reconciling {
+				//maybe also use getter functions on uniPort - perhaps later ...
+				go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
+			} else {
+				logger.Debugw("reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
+			}
+		}
+	}
+}
+
+// Disable UniPortState and update core port state accordingly
+func (dh *deviceHandler) disableUniPortStateUpdate() {
+	for uniNo, uniPort := range dh.uniEntityMap {
+		// only if this port is validated for operState transfer
+		if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
+			logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
+			uniPort.setOperState(vc.OperStatus_UNKNOWN)
+			//maybe also use getter functions on uniPort - perhaps later ...
+			go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
+		}
+	}
+}
+
+// ONU_Active/Inactive announcement on system KAFKA bus
+// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
+func (dh *deviceHandler) sendOnuOperStateEvent(aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
+	var de voltha.DeviceEvent
+	eventContext := make(map[string]string)
+	parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentID, dh.parentID)
+	if err != nil || parentDevice == nil {
+		logger.Errorw("Failed to fetch parent device for OnuEvent",
+			log.Fields{"parentID": dh.parentID, "err": err})
+	}
+	oltSerialNumber := parentDevice.SerialNumber
+
+	eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
+	eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
+	eventContext["serial-number"] = dh.device.SerialNumber
+	eventContext["olt_serial_number"] = oltSerialNumber
+	eventContext["device_id"] = aDeviceID
+	eventContext["registration_id"] = aDeviceID //py: string(device_id)??
+	logger.Debugw("prepare ONU_ACTIVATED event",
+		log.Fields{"DeviceId": aDeviceID, "EventContext": eventContext})
+
+	/* Populating device event body */
+	de.Context = eventContext
+	de.ResourceId = aDeviceID
+	if aOperState == voltha.OperStatus_ACTIVE {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
+		de.Description = fmt.Sprintf("%s Event - %s - %s",
+			cEventObjectType, cOnuActivatedEvent, "Raised")
+	} else {
+		de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
+		de.Description = fmt.Sprintf("%s Event - %s - %s",
+			cEventObjectType, cOnuActivatedEvent, "Cleared")
+	}
+	/* Send event to KAFKA */
+	if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
+		logger.Warnw("could not send ONU_ACTIVATED event",
+			log.Fields{"device-id": aDeviceID, "error": err})
+	}
+	logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
+		log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
+}
+
+// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
+func (dh *deviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
+	chLSFsm := make(chan Message, 2048)
+	var sFsmName string
+	if aAdminState {
+		logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
+		sFsmName = "LockStateFSM"
+	} else {
+		logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
+		sFsmName = "UnLockStateFSM"
+	}
+
+	pDevEntry := dh.getOnuDeviceEntry(true)
+	if pDevEntry == nil {
+		logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
+		return
+	}
+	pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
+		sFsmName, dh.deviceID, chLSFsm)
+	if pLSFsm != nil {
+		if aAdminState {
+			dh.pLockStateFsm = pLSFsm
+		} else {
+			dh.pUnlockStateFsm = pLSFsm
+		}
+		dh.runUniLockFsm(aAdminState)
+	} else {
+		logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
+	}
+}
+
+// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
+func (dh *deviceHandler) runUniLockFsm(aAdminState bool) {
+	/*  Uni Port lock/unlock procedure -
+	 ***** should run via 'adminDone' state and generate the argument requested event *****
+	 */
+	var pLSStatemachine *fsm.FSM
+	if aAdminState {
+		pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
+		//make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
+		if (dh.pUnlockStateFsm != nil) &&
+			(dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
+			_ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
+		}
+	} else {
+		pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
+		//make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
+		if (dh.pLockStateFsm != nil) &&
+			(dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
+			_ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
+		}
+	}
+	if pLSStatemachine != nil {
+		if pLSStatemachine.Is(uniStDisabled) {
+			if err := pLSStatemachine.Event(uniEvStart); err != nil {
+				logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
+				// maybe try a FSM reset and then again ... - TODO!!!
+			} else {
+				/***** LockStateFSM started */
+				logger.Debugw("LockStateFSM started", log.Fields{
+					"state": pLSStatemachine.Current(), "device-id": dh.deviceID})
+			}
+		} else {
+			logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
+				"have": pLSStatemachine.Current(), "device-id": dh.deviceID})
+			// maybe try a FSM reset and then again ... - TODO!!!
+		}
+	} else {
+		logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
+		// maybe try a FSM reset and then again ... - TODO!!!
+	}
+}
+
+//setBackend provides a DB backend for the specified path on the existing KV client
+func (dh *deviceHandler) setBackend(aBasePathKvStore string) *db.Backend {
+	addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
+	logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
+		"BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
+	kvbackend := &db.Backend{
+		Client:    dh.pOpenOnuAc.kvClient,
+		StoreType: dh.pOpenOnuAc.KVStoreType,
+		/* address config update acc. to [VOL-2736] */
+		Address:    addr,
+		Timeout:    dh.pOpenOnuAc.KVStoreTimeout,
+		PathPrefix: aBasePathKvStore}
+
+	return kvbackend
+}
+func (dh *deviceHandler) getFlowOfbFields(apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
+	loAddPcp *uint8, loIPProto *uint32) {
+
+	for _, field := range flow.GetOfbFields(apFlowItem) {
+		switch field.Type {
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
+			{
+				logger.Debugw("FlowAdd type EthType", log.Fields{"device-id": dh.deviceID,
+					"EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
+			{
+				*loIPProto = field.GetIpProto()
+				logger.Debugw("FlowAdd type IpProto", log.Fields{"device-id": dh.deviceID,
+					"IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
+				if *loIPProto == 2 {
+					// some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
+					// avoids installing invalid EVTOCD rule
+					logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
+						log.Fields{"device-id": dh.deviceID,
+							"IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
+					return
+				}
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
+			{
+				*loMatchVlan = uint16(field.GetVlanVid())
+				loMatchVlanMask := uint16(field.GetVlanVidMask())
+				if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
+					loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
+					*loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
+				}
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
+			{
+				*loAddPcp = uint8(field.GetVlanPcp())
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"PCP": loAddPcp})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
+			{
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
+			{
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
+			{
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"IPv4-DST": field.GetIpv4Dst()})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
+			{
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"IPv4-SRC": field.GetIpv4Src()})
+			}
+		case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
+			{
+				logger.Debugw("FlowAdd field type", log.Fields{"device-id": dh.deviceID,
+					"Metadata": field.GetTableMetadata()})
+			}
+			/*
+				default:
+					{
+						//all other entires ignored
+					}
+			*/
+		}
+	} //for all OfbFields
+}
+
+func (dh *deviceHandler) getFlowActions(apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
+	for _, action := range flow.GetActions(apFlowItem) {
+		switch action.Type {
+		/* not used:
+		case of.OfpActionType_OFPAT_OUTPUT:
+			{
+				logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
+					"Output": action.GetOutput()})
+			}
+		*/
+		case of.OfpActionType_OFPAT_PUSH_VLAN:
+			{
+				logger.Debugw("FlowAdd action type", log.Fields{"device-id": dh.deviceID,
+					"PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
+			}
+		case of.OfpActionType_OFPAT_SET_FIELD:
+			{
+				pActionSetField := action.GetSetField()
+				if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
+					logger.Warnw("FlowAdd action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
+						"OxcmClass": pActionSetField.Field.OxmClass})
+				}
+				if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
+					*loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
+					logger.Debugw("FlowAdd Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
+						"SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
+				} else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
+					*loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
+					logger.Debugw("FlowAdd Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
+						"SetPcp": *loSetPcp})
+				} else {
+					logger.Warnw("FlowAdd action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
+						"Type": pActionSetField.Field.GetOfbField().Type})
+				}
+			}
+			/*
+				default:
+					{
+						//all other entires ignored
+					}
+			*/
+		}
+	} //for all Actions
+}
+
+//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
+func (dh *deviceHandler) addFlowItemToUniPort(apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
+	var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE)      //noValidEntry
+	var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
+	var loAddPcp, loSetPcp uint8
+	var loIPProto uint32
+	/* the TechProfileId is part of the flow Metadata - compare also comment within
+	 * OLT-Adapter:openolt_flowmgr.go
+	 *     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 := flow.GetMetadataFromWriteMetadataAction(apFlowItem)
+	if metadata == 0 {
+		logger.Debugw("FlowAdd invalid metadata - abort",
+			log.Fields{"device-id": dh.deviceID})
+		return errors.New("flowAdd invalid metadata")
+	}
+	loTpID := flow.GetTechProfileIDFromWriteMetaData(metadata)
+	logger.Debugw("FlowAdd TechProfileId", log.Fields{"device-id": dh.deviceID, "TP-Id": loTpID})
+
+	dh.getFlowOfbFields(apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
+	if loIPProto == 2 {
+		// some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
+		// avoids installing invalid EVTOCD rule
+		logger.Debugw("FlowAdd type IpProto 2: TT workaround: ignore flow",
+			log.Fields{"device-id": dh.deviceID,
+				"IpProto": strconv.FormatInt(int64(loIPProto), 16)})
+		return nil
+	}
+	dh.getFlowActions(apFlowItem, &loSetPcp, &loSetVlan)
+
+	if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
+		logger.Errorw("FlowAdd aborted - SetVlanId undefined, but MatchVid set", log.Fields{
+			"device-id": dh.deviceID, "UniPort": apUniPort.portNo,
+			"set_vid":   strconv.FormatInt(int64(loSetVlan), 16),
+			"match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
+		//TODO!!: Use DeviceId within the error response to rwCore
+		//  likewise also in other error response cases to calling components as requested in [VOL-3458]
+		return errors.New("flowAdd Set/Match VlanId inconsistent")
+	}
+	if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
+		logger.Debugw("FlowAdd vlan-any/copy", log.Fields{"device-id": dh.deviceID})
+		loSetVlan = loMatchVlan //both 'transparent' (copy any)
+	} else {
+		//looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
+		if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
+			// not set to transparent
+			loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
+		}
+		logger.Debugw("FlowAdd vlan-set", log.Fields{"device-id": dh.deviceID})
+	}
+	if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
+		logger.Errorw("FlowAdd aborted - FSM already running", log.Fields{
+			"device-id": dh.deviceID, "UniPort": apUniPort.portNo})
+		return errors.New("flowAdd FSM already running")
+	}
+	return dh.createVlanFilterFsm(apUniPort,
+		loTpID, loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterDone)
+}
+
+// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
+func (dh *deviceHandler) createVlanFilterFsm(apUniPort *onuUniPort,
+	aTpID uint16, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
+	chVlanFilterFsm := make(chan Message, 2048)
+
+	pDevEntry := dh.getOnuDeviceEntry(true)
+	if pDevEntry == nil {
+		logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
+		return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
+	}
+
+	pVlanFilterFsm := NewUniVlanConfigFsm(dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
+		pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", dh.deviceID, chVlanFilterFsm,
+		dh.pOpenOnuAc.AcceptIncrementalEvto, aMatchVlan, aSetVlan, aSetPcp)
+	if pVlanFilterFsm != nil {
+		dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
+		pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
+		if pVlanFilterStatemachine != nil {
+			if pVlanFilterStatemachine.Is(vlanStDisabled) {
+				if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
+					logger.Warnw("UniVlanConfigFsm: can't start", log.Fields{"err": err})
+					return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
+				}
+				/***** UniVlanConfigFsm started */
+				logger.Debugw("UniVlanConfigFsm started", log.Fields{
+					"state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
+					"UniPort": apUniPort.portNo})
+			} else {
+				logger.Warnw("wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
+					"have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
+				return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
+			}
+		} else {
+			logger.Errorw("UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
+				"device-id": dh.deviceID})
+			return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
+		}
+	} else {
+		logger.Errorw("UniVlanConfigFsm could not be created - abort!!", log.Fields{
+			"device-id": dh.deviceID, "UniPort": apUniPort.portNo})
+		return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
+	}
+	return nil
+}
+
+//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
+func (dh *deviceHandler) verifyUniVlanConfigRequest(apUniPort *onuUniPort) {
+	if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
+		//VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
+		pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
+		if pVlanFilterStatemachine != nil {
+			if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
+				if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
+					logger.Warnw("UniVlanConfigFsm: can't continue processing", log.Fields{"err": err})
+				} else {
+					/***** UniVlanConfigFsm continued */
+					logger.Debugw("UniVlanConfigFsm continued", log.Fields{
+						"state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
+						"UniPort": apUniPort.portNo})
+				}
+			} else {
+				logger.Debugw("no state of UniVlanConfigFsm to be continued", log.Fields{
+					"have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
+			}
+		} else {
+			logger.Debugw("UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
+				"device-id": dh.deviceID})
+		}
+
+	} // else: nothing to do
+}
+
+//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
+// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
+func (dh *deviceHandler) RemoveVlanFilterFsm(apUniPort *onuUniPort) {
+	logger.Debugw("remove UniVlanConfigFsm StateMachine", log.Fields{
+		"device-id": dh.deviceID, "uniPort": apUniPort.portNo})
+	delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
+}
diff --git a/internal/pkg/onuadaptercore/messageTypes.go b/internal/pkg/onuadaptercore/messageTypes.go
new file mode 100644
index 0000000..892d058
--- /dev/null
+++ b/internal/pkg/onuadaptercore/messageTypes.go
@@ -0,0 +1,68 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	gp "github.com/google/gopacket"
+	"github.com/opencord/omci-lib-go"
+)
+
+// MessageType - Message Protocol Type
+type MessageType uint8
+
+const (
+	TestMsg MessageType = iota
+	OMCI
+)
+
+// String - Return the text representation of the message type based on integer
+func (m MessageType) String() string {
+	names := [...]string{
+		"TestMsg",
+		"OMCI",
+	}
+	return names[m]
+}
+
+// Message - message type and data(OMCI)
+type Message struct {
+	Type MessageType
+	Data interface{}
+}
+
+//TestMessageType - message data for various events
+type TestMessageType uint8
+
+const (
+	LoadMibTemplateOk TestMessageType = iota + 1
+	LoadMibTemplateFailed
+	TimeOutOccurred
+	AbortMessageProcessing
+)
+
+//TestMessage - Struct to hold the message data
+//TODO: place holder to have a second interface variant - to be replaced by real variant later on
+type TestMessage struct {
+	TestMessageVal TestMessageType
+}
+
+//OmciMessage - OMCI protocol messages for managing and monitoring ONUs
+type OmciMessage struct {
+	OmciMsg    *omci.OMCI
+	OmciPacket *gp.Packet
+}
diff --git a/internal/pkg/onuadaptercore/mib_download.go b/internal/pkg/onuadaptercore/mib_download.go
new file mode 100644
index 0000000..baf2709
--- /dev/null
+++ b/internal/pkg/onuadaptercore/mib_download.go
@@ -0,0 +1,285 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+	"time"
+
+	"github.com/looplab/fsm"
+
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+func (onuDeviceEntry *OnuDeviceEntry) enterDLStartingState(e *fsm.Event) {
+	logger.Debugw("MibDownload FSM", log.Fields{"Start downloading OMCI MIB in state": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	if onuDeviceEntry.omciMessageReceived == nil {
+		onuDeviceEntry.omciMessageReceived = make(chan bool)
+		logger.Debug("MibDownload FSM - defining the BridgeInit RxChannel")
+	}
+	go onuDeviceEntry.processMibDownloadMessages()
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterCreatingGalState(e *fsm.Event) {
+	logger.Debugw("MibDownload FSM", log.Fields{"Tx create::GAL Ethernet Profile in state": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	meInstance := onuDeviceEntry.PDevOmciCC.sendCreateGalEthernetProfile(context.TODO(), ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterSettingOnu2gState(e *fsm.Event) {
+	logger.Debugw("MibDownload FSM", log.Fields{"Tx Set::ONU2-G in state": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	meInstance := onuDeviceEntry.PDevOmciCC.sendSetOnu2g(context.TODO(), ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterBridgeInitState(e *fsm.Event) {
+	logger.Infow("MibDownload FSM - starting bridge config port loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	go onuDeviceEntry.performInitialBridgeSetup()
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterDownloadedState(e *fsm.Event) {
+	logger.Debugw("MibDownload FSM", log.Fields{"send notification to core in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	onuDeviceEntry.transferSystemEvent(MibDownloadDone)
+	pMibDlFsm := onuDeviceEntry.pMibDownloadFsm
+	if pMibDlFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(dlEvReset)
+			}
+		}(pMibDlFsm)
+	}
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterResettingState(e *fsm.Event) {
+	logger.Debugw("MibDownload FSM resetting", log.Fields{"device-id": onuDeviceEntry.deviceID})
+	pMibDlFsm := onuDeviceEntry.pMibDownloadFsm
+	if pMibDlFsm != nil {
+		// abort running message processing
+		fsmAbortMsg := Message{
+			Type: TestMsg,
+			Data: TestMessage{
+				TestMessageVal: AbortMessageProcessing,
+			},
+		}
+		pMibDlFsm.commChan <- fsmAbortMsg
+
+		//try to restart the FSM to 'disabled'
+		// see DownloadedState: decouple event transfer
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(dlEvRestart)
+			}
+		}(pMibDlFsm)
+	}
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) processMibDownloadMessages( /*ctx context.Context*/ ) {
+	logger.Debugw("Start MibDownload Msg processing", log.Fields{"for device-id": onuDeviceEntry.deviceID})
+loop:
+	for {
+		// case <-ctx.Done():
+		// 	logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": onuDeviceEntry.deviceID})
+		// 	break loop
+		// unless multiple channels are not involved, we should not use select
+		message, ok := <-onuDeviceEntry.pMibDownloadFsm.commChan
+		if !ok {
+			logger.Info("MibDownload Rx Msg", log.Fields{"Message couldn't be read from channel for device-id": onuDeviceEntry.deviceID})
+			// but then we have to ensure a restart of the FSM as well - as exceptional procedure
+			_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvRestart)
+			break loop
+		}
+		logger.Debugw("MibDownload Rx Msg", log.Fields{"Received message for device-id": onuDeviceEntry.deviceID})
+
+		switch message.Type {
+		case TestMsg:
+			msg, _ := message.Data.(TestMessage)
+			if msg.TestMessageVal == AbortMessageProcessing {
+				logger.Infow("MibDownload abort ProcessMsg", log.Fields{"for device-id": onuDeviceEntry.deviceID})
+				break loop
+			}
+			logger.Warnw("MibDownload unknown TestMessage", log.Fields{"device-id": onuDeviceEntry.deviceID, "MessageVal": msg.TestMessageVal})
+		case OMCI:
+			msg, _ := message.Data.(OmciMessage)
+			onuDeviceEntry.handleOmciMibDownloadMessage(msg)
+		default:
+			logger.Warn("MibDownload Rx Msg", log.Fields{"Unknown message type received for device-id": onuDeviceEntry.deviceID,
+				"message.Type": message.Type})
+		}
+
+	}
+	logger.Infow("End MibDownload Msg processing", log.Fields{"for device-id": onuDeviceEntry.deviceID})
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleOmciMibDownloadMessage(msg OmciMessage) {
+	logger.Debugw("Rx OMCI MibDownload Msg", log.Fields{"device-id": onuDeviceEntry.deviceID,
+		"msgType": msg.OmciMsg.MessageType})
+
+	switch msg.OmciMsg.MessageType {
+	case omci.CreateResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
+			if msgLayer == nil {
+				logger.Error("Omci Msg layer could not be detected for CreateResponse")
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.CreateResponse)
+			if !msgOk {
+				logger.Error("Omci Msg layer could not be assigned for CreateResponse")
+				return
+			}
+			logger.Debugw("CreateResponse Data", log.Fields{"device-id": onuDeviceEntry.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+				// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+				return
+			}
+			// maybe there is a way of pushing the specific create response type generally to the FSM
+			//   and let the FSM verify, if the response was according to current state
+			//   and possibly store the element to DB and progress - maybe some future option ...
+			// but as that is not straightforward to me I insert the type checkes manually here
+			//   and feed the FSM with only 'pre-defined' events ...
+			if msgObj.EntityClass == onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetClassID() &&
+				msgObj.EntityInstance == onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetEntityID() {
+				//store the created ME into DB //TODO??? obviously the Python code does not store the config ...
+				// if, then something like:
+				//onuDeviceEntry.pOnuDB.StoreMe(msgObj)
+
+				// maybe we can use just the same eventName for different state transitions like "forward"
+				//   - might be checked, but so far I go for sure and have to inspect the concrete state events ...
+				switch onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetName() {
+				case "GalEthernetProfile":
+					{ // let the FSM proceed ...
+						_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvRxGalResp)
+					}
+				case "MacBridgeServiceProfile",
+					"MacBridgePortConfigurationData",
+					"ExtendedVlanTaggingOperationConfigurationData":
+					{ // let bridge init proceed by stopping the wait function
+						onuDeviceEntry.omciMessageReceived <- true
+					}
+				}
+			}
+		} //CreateResponseType
+
+	case omci.SetResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
+			if msgLayer == nil {
+				logger.Error("Omci Msg layer could not be detected for SetResponse")
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.SetResponse)
+			if !msgOk {
+				logger.Error("Omci Msg layer could not be assigned for SetResponse")
+				return
+			}
+			logger.Debugw("SetResponse Data", log.Fields{"device-id": onuDeviceEntry.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw("Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+				// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+				return
+			}
+			// compare comments above for CreateResponse (apply also here ...)
+			if msgObj.EntityClass == onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetClassID() &&
+				msgObj.EntityInstance == onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetEntityID() {
+				//store the created ME into DB //TODO??? obviously the Python code does not store the config ...
+				// if, then something like:
+				//onuDeviceEntry.pOnuDB.StoreMe(msgObj)
+
+				switch onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetName() {
+				case "Onu2G":
+					{ // let the FSM proceed ...
+						_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvRxOnu2gResp)
+					}
+					//so far that was the only MibDownlad Set Element ...
+				}
+			}
+		} //SetResponseType
+	default:
+		{
+			logger.Errorw("Rx OMCI MibDownload unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
+			return
+		}
+	} // switch msg.OmciMsg.MessageType
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) performInitialBridgeSetup() {
+	for uniNo, uniPort := range onuDeviceEntry.baseDeviceHandler.uniEntityMap {
+		logger.Debugw("Starting IntialBridgeSetup", log.Fields{
+			"device-id": onuDeviceEntry.deviceID, "for PortNo": uniNo})
+
+		//create MBSP
+		meInstance := onuDeviceEntry.PDevOmciCC.sendCreateMBServiceProfile(
+			context.TODO(), uniPort, ConstDefaultOmciTimeout, true)
+		onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+		//verify response
+		err := onuDeviceEntry.waitforOmciResponse(meInstance)
+		if err != nil {
+			logger.Error("InitialBridgeSetup failed at MBSP, aborting MIB Download!")
+			_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvReset)
+			return
+		}
+
+		//create MBPCD
+		meInstance = onuDeviceEntry.PDevOmciCC.sendCreateMBPConfigData(
+			context.TODO(), uniPort, ConstDefaultOmciTimeout, true)
+		onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+		//verify response
+		err = onuDeviceEntry.waitforOmciResponse(meInstance)
+		if err != nil {
+			logger.Error("InitialBridgeSetup failed at MBPCD, aborting MIB Download!")
+			_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvReset)
+			return
+		}
+
+		//create EVTOCD
+		meInstance = onuDeviceEntry.PDevOmciCC.sendCreateEVTOConfigData(
+			context.TODO(), uniPort, ConstDefaultOmciTimeout, true)
+		onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+		//verify response
+		err = onuDeviceEntry.waitforOmciResponse(meInstance)
+		if err != nil {
+			logger.Error("InitialBridgeSetup failed at EVTOCD, aborting MIB Download!")
+			_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvReset)
+			return
+		}
+	}
+	logger.Infow("IntialBridgeSetup finished", log.Fields{"device-id": onuDeviceEntry.deviceID})
+	_ = onuDeviceEntry.pMibDownloadFsm.pFsm.Event(dlEvRxBridgeResp)
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) waitforOmciResponse(apMeInstance *me.ManagedEntity) error {
+	select {
+	case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw("MibDownload-bridge-init timeout", log.Fields{"for device-id": onuDeviceEntry.deviceID})
+		return errors.New("mibDownloadBridgeInit timeout")
+	case success := <-onuDeviceEntry.omciMessageReceived:
+		if success {
+			logger.Debug("MibDownload-bridge-init response received")
+			return nil
+		}
+		// should not happen so far
+		logger.Warnw("MibDownload-bridge-init response error", log.Fields{"for device-id": onuDeviceEntry.deviceID})
+		return errors.New("mibDownloadBridgeInit responseError")
+	}
+}
diff --git a/internal/pkg/onuadaptercore/mib_sync.go b/internal/pkg/onuadaptercore/mib_sync.go
new file mode 100644
index 0000000..a42d3ce
--- /dev/null
+++ b/internal/pkg/onuadaptercore/mib_sync.go
@@ -0,0 +1,533 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/looplab/fsm"
+
+	"time"
+
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+var supportedClassIds = []me.ClassID{
+	me.CardholderClassID,                              // 5
+	me.CircuitPackClassID,                             // 6
+	me.SoftwareImageClassID,                           // 7
+	me.PhysicalPathTerminationPointEthernetUniClassID, // 11
+	me.OltGClassID,                                    // 131
+	me.OnuPowerSheddingClassID,                        // 133
+	me.IpHostConfigDataClassID,                        // 134
+	me.OnuGClassID,                                    // 256
+	me.Onu2GClassID,                                   // 257
+	me.TContClassID,                                   // 262
+	me.AniGClassID,                                    // 263
+	me.UniGClassID,                                    // 264
+	me.PriorityQueueClassID,                           // 277
+	me.TrafficSchedulerClassID,                        // 278
+	me.VirtualEthernetInterfacePointClassID,           // 329
+	me.EnhancedSecurityControlClassID,                 // 332
+	me.OnuDynamicPowerManagementControlClassID,        // 336
+}
+
+var fsmMsg TestMessageType
+
+func (onuDeviceEntry *OnuDeviceEntry) enterStartingState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start processing MibSync-msgs in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	onuDeviceEntry.pOnuDB = newOnuDeviceDB(context.TODO(), onuDeviceEntry)
+	go onuDeviceEntry.processMibSyncMessages()
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterResettingMibState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start MibTemplate processing in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+
+	logger.Debugw("MibSync FSM", log.Fields{"send mibReset in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	_ = onuDeviceEntry.PDevOmciCC.sendMibReset(context.TODO(), ConstDefaultOmciTimeout, true)
+
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterGettingVendorAndSerialState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start getting VendorId and SerialNumber in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	requestedAttributes := me.AttributeValueMap{"VendorId": "", "SerialNumber": 0}
+	meInstance := onuDeviceEntry.PDevOmciCC.sendGetMe(context.TODO(), me.OnuGClassID, onugMeID, requestedAttributes, ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterGettingEquipmentIDState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start getting EquipmentId in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	requestedAttributes := me.AttributeValueMap{"EquipmentId": ""}
+	meInstance := onuDeviceEntry.PDevOmciCC.sendGetMe(context.TODO(), me.Onu2GClassID, onu2gMeID, requestedAttributes, ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterGettingFirstSwVersionState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start getting IsActive and Version of first SW-image in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	requestedAttributes := me.AttributeValueMap{"IsActive": 0, "Version": ""}
+	meInstance := onuDeviceEntry.PDevOmciCC.sendGetMe(context.TODO(), me.SoftwareImageClassID, firstSwImageMeID, requestedAttributes, ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterGettingSecondSwVersionState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start getting IsActive and Version of second SW-image in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	requestedAttributes := me.AttributeValueMap{"IsActive": 0, "Version": ""}
+	meInstance := onuDeviceEntry.PDevOmciCC.sendGetMe(context.TODO(), me.SoftwareImageClassID, secondSwImageMeID, requestedAttributes, ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterGettingMacAddressState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start getting MacAddress in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	requestedAttributes := me.AttributeValueMap{"MacAddress": ""}
+	meInstance := onuDeviceEntry.PDevOmciCC.sendGetMe(context.TODO(), me.IpHostConfigDataClassID, ipHostConfigDataMeID, requestedAttributes, ConstDefaultOmciTimeout, true)
+	onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterGettingMibTemplate(e *fsm.Event) {
+
+	for i := firstSwImageMeID; i <= secondSwImageMeID; i++ {
+		if onuDeviceEntry.swImages[i].isActive > 0 {
+			onuDeviceEntry.activeSwVersion = onuDeviceEntry.swImages[i].version
+		}
+	}
+
+	meStoredFromTemplate := false
+	path := fmt.Sprintf(cSuffixMibTemplateKvStore, onuDeviceEntry.vendorID, onuDeviceEntry.equipmentID, onuDeviceEntry.activeSwVersion)
+	logger.Debugw("MibSync FSM - MibTemplate - etcd search string", log.Fields{"path": path})
+	Value, err := onuDeviceEntry.mibTemplateKVStore.Get(context.TODO(), path)
+	if err == nil {
+		if Value != nil {
+			logger.Debugf("MibSync FSM - MibTemplate read: Key: %s, Value: %s  %s", Value.Key, Value.Value)
+
+			// swap out tokens with specific data
+			mibTmpString, _ := kvstore.ToString(Value.Value)
+			mibTmpString2 := strings.Replace(mibTmpString, "%SERIAL_NUMBER%", onuDeviceEntry.serialNumber, -1)
+			mibTmpString = strings.Replace(mibTmpString2, "%MAC_ADDRESS%", onuDeviceEntry.macAddress, -1)
+			mibTmpBytes := []byte(mibTmpString)
+			logger.Debugf("MibSync FSM - MibTemplate tokens swapped out: %s", mibTmpBytes)
+
+			var fistLevelMap map[string]interface{}
+			if err = json.Unmarshal(mibTmpBytes, &fistLevelMap); err != nil {
+				logger.Error("MibSync FSM - Failed to unmarshal template", log.Fields{"error": err, "device-id": onuDeviceEntry.deviceID})
+			} else {
+				for fistLevelKey, firstLevelValue := range fistLevelMap {
+					logger.Debugw("MibSync FSM - fistLevelKey", log.Fields{"fistLevelKey": fistLevelKey})
+					if uint16ValidNumber, err := strconv.ParseUint(fistLevelKey, 10, 16); err == nil {
+						meClassID := me.ClassID(uint16ValidNumber)
+						logger.Debugw("MibSync FSM - fistLevelKey is a number in uint16-range", log.Fields{"uint16ValidNumber": uint16ValidNumber})
+						if isSupportedClassID(meClassID) {
+							logger.Debugw("MibSync FSM - fistLevelKey is a supported classID", log.Fields{"meClassID": meClassID})
+							secondLevelMap := firstLevelValue.(map[string]interface{})
+							for secondLevelKey, secondLevelValue := range secondLevelMap {
+								logger.Debugw("MibSync FSM - secondLevelKey", log.Fields{"secondLevelKey": secondLevelKey})
+								if uint16ValidNumber, err := strconv.ParseUint(secondLevelKey, 10, 16); err == nil {
+									meEntityID := uint16(uint16ValidNumber)
+									logger.Debugw("MibSync FSM - secondLevelKey is a number and a valid EntityId", log.Fields{"meEntityID": meEntityID})
+									thirdLevelMap := secondLevelValue.(map[string]interface{})
+									for thirdLevelKey, thirdLevelValue := range thirdLevelMap {
+										if thirdLevelKey == "Attributes" {
+											logger.Debugw("MibSync FSM - thirdLevelKey refers to attributes", log.Fields{"thirdLevelKey": thirdLevelKey})
+											attributesMap := thirdLevelValue.(map[string]interface{})
+											logger.Debugw("MibSync FSM - attributesMap", log.Fields{"attributesMap": attributesMap})
+											onuDeviceEntry.pOnuDB.PutMe(meClassID, meEntityID, attributesMap)
+											meStoredFromTemplate = true
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		} else {
+			logger.Debugw("No MIB template found", log.Fields{"path": path, "device-id": onuDeviceEntry.deviceID})
+		}
+	} else {
+		logger.Errorf("Get from kvstore operation failed for path %s", path)
+	}
+	if meStoredFromTemplate {
+		logger.Debug("MibSync FSM - valid MEs stored from template")
+		onuDeviceEntry.pOnuDB.logMeDb()
+		fsmMsg = LoadMibTemplateOk
+	} else {
+		logger.Debug("MibSync FSM - no valid MEs stored from template - perform MIB-upload!")
+		fsmMsg = LoadMibTemplateFailed
+	}
+
+	mibSyncMsg := Message{
+		Type: TestMsg,
+		Data: TestMessage{
+			TestMessageVal: fsmMsg,
+		},
+	}
+	onuDeviceEntry.pMibUploadFsm.commChan <- mibSyncMsg
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterUploadingState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"send MibUpload in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	_ = onuDeviceEntry.PDevOmciCC.sendMibUpload(context.TODO(), ConstDefaultOmciTimeout, true)
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterInSyncState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"send notification to core in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	onuDeviceEntry.transferSystemEvent(MibDatabaseSync)
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterExaminingMdsState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start GetMds processing in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	logger.Debug("function not implemented yet")
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterResynchronizingState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start MibResync processing in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	logger.Debug("function not implemented yet")
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterAuditingState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start MibResync processing in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	logger.Debug("function not implemented yet")
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) enterOutOfSyncState(e *fsm.Event) {
+	logger.Debugw("MibSync FSM", log.Fields{"Start  MibReconcile processing in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+	logger.Debug("function not implemented yet")
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) processMibSyncMessages( /*ctx context.Context*/ ) {
+	logger.Debugw("MibSync Msg", log.Fields{"Start routine to process OMCI-messages for device-id": onuDeviceEntry.deviceID})
+loop:
+	for {
+		// case <-ctx.Done():
+		// 	logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": onuDeviceEntry.deviceID})
+		// 	break loop
+		message, ok := <-onuDeviceEntry.pMibUploadFsm.commChan
+		if !ok {
+			logger.Info("MibSync Msg", log.Fields{"Message couldn't be read from channel for device-id": onuDeviceEntry.deviceID})
+			break loop
+		}
+		logger.Debugw("MibSync Msg", log.Fields{"Received message on ONU MibSyncChan for device-id": onuDeviceEntry.deviceID})
+
+		switch message.Type {
+		case TestMsg:
+			msg, _ := message.Data.(TestMessage)
+			onuDeviceEntry.handleTestMsg(msg)
+		case OMCI:
+			msg, _ := message.Data.(OmciMessage)
+			onuDeviceEntry.handleOmciMessage(msg)
+		default:
+			logger.Warn("MibSync Msg", log.Fields{"Unknown message type received for device-id": onuDeviceEntry.deviceID, "message.Type": message.Type})
+		}
+	}
+	logger.Info("MibSync Msg", log.Fields{"Stopped handling of MibSyncChan for device-id": onuDeviceEntry.deviceID})
+	_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvStop)
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleTestMsg(msg TestMessage) {
+
+	logger.Debugw("MibSync Msg", log.Fields{"TestMessage received for device-id": onuDeviceEntry.deviceID, "msg.TestMessageVal": msg.TestMessageVal})
+
+	switch msg.TestMessageVal {
+	case LoadMibTemplateFailed:
+		_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvUploadMib)
+		logger.Debugw("MibSync Msg", log.Fields{"state": string(onuDeviceEntry.pMibUploadFsm.pFsm.Current())})
+	case LoadMibTemplateOk:
+		_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvSuccess)
+		logger.Debugw("MibSync Msg", log.Fields{"state": string(onuDeviceEntry.pMibUploadFsm.pFsm.Current())})
+	default:
+		logger.Warn("MibSync Msg", log.Fields{"Unknown message type received for device-id": onuDeviceEntry.deviceID, "msg.TestMessageVal": msg.TestMessageVal})
+	}
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleOmciMibResetResponseMessage(msg OmciMessage) {
+	if onuDeviceEntry.pMibUploadFsm.pFsm.Is(ulStResettingMib) {
+		msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeMibResetResponse)
+		if msgLayer != nil {
+			msgObj, msgOk := msgLayer.(*omci.MibResetResponse)
+			if msgOk {
+				logger.Debugw("MibResetResponse Data", log.Fields{"data-fields": msgObj})
+				if msgObj.Result == me.Success {
+					// trigger retrieval of VendorId and SerialNumber
+					_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvGetVendorAndSerial)
+					return
+				}
+				logger.Errorw("Omci MibResetResponse Error", log.Fields{"Error": msgObj.Result})
+			} else {
+				logger.Error("Omci Msg layer could not be assigned")
+			}
+		} else {
+			logger.Error("Omci Msg layer could not be detected")
+		}
+	} else {
+		logger.Errorw("Omci MibResetResponse received", log.Fields{"in state ": onuDeviceEntry.pMibUploadFsm.pFsm.Current})
+	}
+	logger.Info("MibSync Msg", log.Fields{"Stopped handling of MibSyncChan for device-id": onuDeviceEntry.deviceID})
+	_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvStop)
+
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleOmciMibUploadResponseMessage(msg OmciMessage) {
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeMibUploadResponse)
+	if msgLayer == nil {
+		logger.Error("Omci Msg layer could not be detected")
+		return
+	}
+	msgObj, msgOk := msgLayer.(*omci.MibUploadResponse)
+	if !msgOk {
+		logger.Error("Omci Msg layer could not be assigned")
+		return
+	}
+	logger.Debugw("MibUploadResponse Data for:", log.Fields{"deviceId": onuDeviceEntry.deviceID, "data-fields": msgObj})
+	/* to be verified / reworked !!! */
+	onuDeviceEntry.PDevOmciCC.uploadNoOfCmds = msgObj.NumberOfCommands
+	if onuDeviceEntry.PDevOmciCC.uploadSequNo < onuDeviceEntry.PDevOmciCC.uploadNoOfCmds {
+		_ = onuDeviceEntry.PDevOmciCC.sendMibUploadNext(context.TODO(), ConstDefaultOmciTimeout, true)
+	} else {
+		logger.Error("Invalid number of commands received for:", log.Fields{"deviceId": onuDeviceEntry.deviceID, "uploadNoOfCmds": onuDeviceEntry.PDevOmciCC.uploadNoOfCmds})
+		//TODO right action?
+		_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvTimeout)
+	}
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleOmciMibUploadNextResponseMessage(msg OmciMessage) {
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeMibUploadNextResponse)
+	if msgLayer == nil {
+		logger.Error("Omci Msg layer could not be detected")
+		return
+	}
+	msgObj, msgOk := msgLayer.(*omci.MibUploadNextResponse)
+	if !msgOk {
+		logger.Error("Omci Msg layer could not be assigned")
+		return
+	}
+	if onuDeviceEntry.mibDebugLevel == "VERBOSE" {
+		logger.Debugw("MibUploadNextResponse Data for:", log.Fields{"deviceId": onuDeviceEntry.deviceID, "data-fields": msgObj})
+	}
+	meClassID := msgObj.ReportedME.GetClassID()
+	meEntityID := msgObj.ReportedME.GetEntityID()
+	meAttributes := msgObj.ReportedME.GetAttributeValueMap()
+
+	onuDeviceEntry.pOnuDB.PutMe(meClassID, meEntityID, meAttributes)
+
+	if onuDeviceEntry.PDevOmciCC.uploadSequNo < onuDeviceEntry.PDevOmciCC.uploadNoOfCmds {
+		_ = onuDeviceEntry.PDevOmciCC.sendMibUploadNext(context.TODO(), ConstDefaultOmciTimeout, true)
+	} else {
+		onuDeviceEntry.pOnuDB.logMeDb()
+		err := onuDeviceEntry.createAndPersistMibTemplate()
+		if err != nil {
+			logger.Errorw("MibSync - MibTemplate - Failed to create and persist the mib template", log.Fields{"error": err, "device-id": onuDeviceEntry.deviceID})
+		}
+
+		_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvSuccess)
+	}
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleOmciGetResponseMessage(msg OmciMessage) {
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
+	if msgLayer != nil {
+		msgObj, msgOk := msgLayer.(*omci.GetResponse)
+		if msgOk {
+			logger.Debugw("MibSync FSM - GetResponse Data", log.Fields{"deviceId": onuDeviceEntry.deviceID, "data-fields": msgObj})
+			if msgObj.Result == me.Success {
+				entityID := onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetEntityID()
+				if msgObj.EntityClass == onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetClassID() && msgObj.EntityInstance == entityID {
+					meAttributes := msgObj.Attributes
+					meInstance := onuDeviceEntry.PDevOmciCC.pLastTxMeInstance.GetName()
+					if onuDeviceEntry.mibDebugLevel == "VERBOSE" {
+						logger.Debugf("MibSync FSM - GetResponse Data for %s", log.Fields{"deviceId": onuDeviceEntry.deviceID, "data-fields": msgObj}, meInstance)
+					}
+					switch meInstance {
+					case "OnuG":
+						onuDeviceEntry.vendorID = fmt.Sprintf("%s", meAttributes["VendorId"])
+						snBytes, _ := me.InterfaceToOctets(meAttributes["SerialNumber"])
+						if onugSerialNumberLen == len(snBytes) {
+							snVendorPart := fmt.Sprintf("%s", snBytes[:4])
+							snNumberPart := hex.EncodeToString(snBytes[4:])
+							onuDeviceEntry.serialNumber = snVendorPart + snNumberPart
+							logger.Debugw("MibSync FSM - GetResponse Data for Onu-G - VendorId/SerialNumber", log.Fields{"deviceId": onuDeviceEntry.deviceID,
+								"onuDeviceEntry.vendorID": onuDeviceEntry.vendorID, "onuDeviceEntry.serialNumber": onuDeviceEntry.serialNumber})
+						} else {
+							logger.Errorw("MibSync FSM - SerialNumber has wrong length", log.Fields{"deviceId": onuDeviceEntry.deviceID, "length": len(snBytes)})
+						}
+						// trigger retrieval of EquipmentId
+						_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvGetEquipmentID)
+						return
+					case "Onu2G":
+						onuDeviceEntry.equipmentID = fmt.Sprintf("%s", meAttributes["EquipmentId"])
+						logger.Debugw("MibSync FSM - GetResponse Data for Onu2-G - EquipmentId", log.Fields{"deviceId": onuDeviceEntry.deviceID,
+							"onuDeviceEntry.equipmentID": onuDeviceEntry.equipmentID})
+						// trigger retrieval of 1st SW-image info
+						_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvGetFirstSwVersion)
+						return
+					case "SoftwareImage":
+						if entityID <= secondSwImageMeID {
+							onuDeviceEntry.swImages[entityID].version = fmt.Sprintf("%s", meAttributes["Version"])
+							onuDeviceEntry.swImages[entityID].isActive = meAttributes["IsActive"].(uint8)
+							logger.Debugw("MibSync FSM - GetResponse Data for SoftwareImage - Version/IsActive",
+								log.Fields{"deviceId": onuDeviceEntry.deviceID, "entityID": entityID,
+									"version": onuDeviceEntry.swImages[entityID].version, "isActive": onuDeviceEntry.swImages[entityID].isActive})
+						} else {
+							//TODO: error handling
+							logger.Errorw("MibSync FSM - Failed to GetResponse Data for SoftwareImage", log.Fields{"deviceId": onuDeviceEntry.deviceID})
+
+						}
+						if firstSwImageMeID == entityID {
+							_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvGetSecondSwVersion)
+							return
+						} else if secondSwImageMeID == entityID {
+							_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvGetMacAddress)
+							return
+						}
+					case "IpHostConfigData":
+						macBytes, _ := me.InterfaceToOctets(meAttributes["MacAddress"])
+						if omciMacAddressLen == len(macBytes) {
+							onuDeviceEntry.macAddress = hex.EncodeToString(macBytes[:])
+							logger.Debugw("MibSync FSM - GetResponse Data for IpHostConfigData - MacAddress", log.Fields{"deviceId": onuDeviceEntry.deviceID,
+								"onuDeviceEntry.macAddress": onuDeviceEntry.macAddress})
+						} else {
+							logger.Errorw("MibSync FSM - MacAddress wrong length", log.Fields{"deviceId": onuDeviceEntry.deviceID, "length": len(macBytes)})
+						}
+						// trigger retrieval of mib template
+						_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvGetMibTemplate)
+						return
+					}
+				}
+			} else {
+				logger.Errorw("Omci GetResponse Error", log.Fields{"Error": msgObj.Result})
+			}
+		} else {
+			logger.Error("Omci Msg layer could not be assigned for GetResponse")
+		}
+	} else {
+		logger.Error("Omci Msg layer could not be detected for GetResponse")
+	}
+	logger.Info("MibSync Msg", log.Fields{"Stopped handling of MibSyncChan for device-id": onuDeviceEntry.deviceID})
+	_ = onuDeviceEntry.pMibUploadFsm.pFsm.Event(ulEvStop)
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) handleOmciMessage(msg OmciMessage) {
+	if onuDeviceEntry.mibDebugLevel == "VERBOSE" {
+		logger.Debugw("MibSync Msg", log.Fields{"OmciMessage received for device-id": onuDeviceEntry.deviceID,
+			"msgType": msg.OmciMsg.MessageType})
+	}
+	switch msg.OmciMsg.MessageType {
+	case omci.MibResetResponseType:
+		onuDeviceEntry.handleOmciMibResetResponseMessage(msg)
+
+	case omci.MibUploadResponseType:
+		onuDeviceEntry.handleOmciMibUploadResponseMessage(msg)
+
+	case omci.MibUploadNextResponseType:
+		onuDeviceEntry.handleOmciMibUploadNextResponseMessage(msg)
+
+	case omci.GetResponseType:
+		onuDeviceEntry.handleOmciGetResponseMessage(msg)
+
+	}
+}
+
+func isSupportedClassID(meClassID me.ClassID) bool {
+	for _, v := range supportedClassIds {
+		if v == meClassID {
+			return true
+		}
+	}
+	return false
+}
+
+func (onuDeviceEntry *OnuDeviceEntry) mibDbVolatileDict() error {
+	logger.Debug("MibVolatileDict- running from default Entry code")
+	return errors.New("not_implemented")
+}
+
+// createAndPersistMibTemplate method creates a mib template for the device id when operator enables the ONU device for the first time.
+// We are creating a placeholder for "SerialNumber" for ME Class ID 6 and 256 and "MacAddress" for ME Class ID 134 in the template
+// and then storing the template into etcd "service/voltha/omci_mibs/templates/verdor_id/equipment_id/software_version" path.
+func (onuDeviceEntry *OnuDeviceEntry) createAndPersistMibTemplate() error {
+	path := fmt.Sprintf(cSuffixMibTemplateKvStore, onuDeviceEntry.vendorID, onuDeviceEntry.equipmentID, onuDeviceEntry.activeSwVersion)
+	logger.Debugw("MibSync - MibTemplate - key name", log.Fields{"path": path})
+	currentTime := time.Now()
+
+	templateMap := make(map[string]interface{})
+	templateMap["TemplateName"] = path
+	templateMap["TemplateCreated"] = currentTime.Format("2006-01-02 15:04:05.000000")
+
+	firstLevelMap := onuDeviceEntry.pOnuDB.meDb
+	for firstLevelKey, firstLevelValue := range firstLevelMap {
+		logger.Debugw("MibSync - MibTemplate - firstLevelKey", log.Fields{"firstLevelKey": firstLevelKey})
+		classID := strconv.Itoa(int(firstLevelKey))
+
+		secondLevelMap := make(map[string]interface{})
+		for secondLevelKey, secondLevelValue := range firstLevelValue {
+			thirdLevelMap := make(map[string]interface{})
+			entityID := strconv.Itoa(int(secondLevelKey))
+			thirdLevelMap["Attributes"] = secondLevelValue
+			thirdLevelMap["InstanceId"] = entityID
+			secondLevelMap[entityID] = thirdLevelMap
+			if classID == "6" || classID == "256" {
+				forthLevelMap := map[string]interface{}(thirdLevelMap["Attributes"].(me.AttributeValueMap))
+				delete(forthLevelMap, "SerialNumber")
+				forthLevelMap["SerialNumber"] = "%SERIAL_NUMBER%"
+
+			}
+			if classID == "134" {
+				forthLevelMap := map[string]interface{}(thirdLevelMap["Attributes"].(me.AttributeValueMap))
+				delete(forthLevelMap, "MacAddress")
+				forthLevelMap["MacAddress"] = "%MAC_ADDRESS%"
+			}
+		}
+		secondLevelMap["ClassId"] = classID
+		templateMap[classID] = secondLevelMap
+	}
+	mibTemplate, err := json.Marshal(&templateMap)
+	if err != nil {
+		logger.Errorw("MibSync - MibTemplate - Failed to marshal mibTemplate", log.Fields{"error": err, "device-id": onuDeviceEntry.deviceID})
+		return err
+	}
+	err = onuDeviceEntry.mibTemplateKVStore.Put(context.TODO(), path, string(mibTemplate))
+	if err != nil {
+		logger.Errorw("MibSync - MibTemplate - Failed to store template in etcd", log.Fields{"error": err, "device-id": onuDeviceEntry.deviceID})
+		return err
+	}
+	logger.Debugw("MibSync - MibTemplate - Stored the template to etcd", log.Fields{"device-id": onuDeviceEntry.deviceID})
+	return nil
+}
+
+// func (onuDeviceEntry *OnuDeviceEntry) MibTemplateTask() error {
+// 	return errors.New("not_implemented")
+// }
+// func (onuDeviceEntry *OnuDeviceEntry) MibUploadTask() error {
+// 	return errors.New("not_implemented")
+// }
+// func (onuDeviceEntry *OnuDeviceEntry) GetMdsTask() error {
+// 	return errors.New("not_implemented")
+// }
+// func (onuDeviceEntry *OnuDeviceEntry) MibResyncTask() error {
+// 	return errors.New("not_implemented")
+// }
+// func (onuDeviceEntry *OnuDeviceEntry) MibReconcileTask() error {
+// 	return errors.New("not_implemented")
+// }
diff --git a/internal/pkg/onuadaptercore/olt_onu_msg.go b/internal/pkg/onuadaptercore/olt_onu_msg.go
new file mode 100644
index 0000000..f18910a
--- /dev/null
+++ b/internal/pkg/onuadaptercore/olt_onu_msg.go
@@ -0,0 +1,67 @@
+/*
+ * 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 adaptercoreonu
+
+import (
+	"context"
+	"encoding/json"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+	oop "github.com/opencord/voltha-protos/v3/go/openolt"
+)
+
+//AdditionalMessage ...
+type AdditionalMessage struct {
+}
+
+/*
+func (dh *deviceHandler) receivedMsgFromOlt(msg *ic.InterAdapterMessage) error {
+	msgBody := msg.GetBody()
+	ind := &oop.OnuIndication{}
+
+	err := ptypes.UnmarshalAny(msgBody, ind)
+	if err != nil {
+		logger.Debugw("cannot-unmarshal-onu-indication-body", log.Fields{"error": err})
+	} else {
+		var info AdditionalMessage
+		err = json.Unmarshal(ind.SerialNumber.VendorSpecific, &info)
+		if err != nil {
+			logger.Debugw("cannot-unmarshal-additional-message", log.Fields{"error": err})
+		}
+	}
+
+	return err
+}
+*/
+func (dh *deviceHandler) sendMsgToOlt(ctx context.Context, msg string, option interface{}) error {
+	bytes, _ := json.Marshal(option)
+	info := oop.OnuIndication{
+		SerialNumber: &oop.SerialNumber{
+			VendorSpecific: bytes,
+		},
+	}
+
+	err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &info,
+		ic.InterAdapterMessageType_ONU_IND_REQUEST,
+		dh.DeviceType, dh.ProxyAddressType,
+		dh.deviceID, dh.parentID, msg)
+
+	if err != nil {
+		logger.Debugw("err-sending-message", log.Fields{"device": dh})
+	}
+	return err
+}
diff --git a/internal/pkg/onuadaptercore/omci_ani_config.go b/internal/pkg/onuadaptercore/omci_ani_config.go
new file mode 100644
index 0000000..d7c496c
--- /dev/null
+++ b/internal/pkg/onuadaptercore/omci_ani_config.go
@@ -0,0 +1,782 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"strconv"
+	"time"
+
+	"github.com/cevaris/ordered_map"
+	"github.com/looplab/fsm"
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+const (
+	aniEvStart           = "uniEvStart"
+	aniEvStartConfig     = "aniEvStartConfig"
+	aniEvRxDot1pmapCResp = "aniEvRxDot1pmapCResp"
+	aniEvRxMbpcdResp     = "aniEvRxMbpcdResp"
+	aniEvRxTcontsResp    = "aniEvRxTcontsResp"
+	aniEvRxGemntcpsResp  = "aniEvRxGemntcpsResp"
+	aniEvRxGemiwsResp    = "aniEvRxGemiwsResp"
+	aniEvRxPrioqsResp    = "aniEvRxPrioqsResp"
+	aniEvRxDot1pmapSResp = "aniEvRxDot1pmapSResp"
+	aniEvTimeoutSimple   = "aniEvTimeoutSimple"
+	aniEvTimeoutMids     = "aniEvTimeoutMids"
+	aniEvReset           = "aniEvReset"
+	aniEvRestart         = "aniEvRestart"
+)
+const (
+	aniStDisabled            = "aniStDisabled"
+	aniStStarting            = "aniStStarting"
+	aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
+	aniStCreatingMBPCD       = "aniStCreatingMBPCD"
+	aniStSettingTconts       = "aniStSettingTconts"
+	aniStCreatingGemNCTPs    = "aniStCreatingGemNCTPs"
+	aniStCreatingGemIWs      = "aniStCreatingGemIWs"
+	aniStSettingPQs          = "aniStSettingPQs"
+	aniStSettingDot1PMapper  = "aniStSettingDot1PMapper"
+	aniStConfigDone          = "aniStConfigDone"
+	aniStResetting           = "aniStResetting"
+)
+
+type ponAniGemPortAttribs struct {
+	gemPortID   uint16
+	upQueueID   uint16
+	downQueueID uint16
+	direction   uint8
+	qosPolicy   string
+	weight      uint8
+	pbitString  string
+}
+
+//uniPonAniConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
+type uniPonAniConfigFsm struct {
+	pOmciCC                  *omciCC
+	pOnuUniPort              *onuUniPort
+	pUniTechProf             *onuUniTechProf
+	pOnuDB                   *onuDeviceDB
+	techProfileID            uint16
+	requestEvent             OnuDeviceEvent
+	omciMIdsResponseReceived chan bool //separate channel needed for checking multiInstance OMCI message responses
+	pAdaptFsm                *AdapterFsm
+	aniConfigCompleted       bool
+	chSuccess                chan<- uint8
+	procStep                 uint8
+	chanSet                  bool
+	mapperSP0ID              uint16
+	macBPCD0ID               uint16
+	tcont0ID                 uint16
+	alloc0ID                 uint16
+	gemPortAttribsSlice      []ponAniGemPortAttribs
+}
+
+//newUniPonAniConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
+func newUniPonAniConfigFsm(apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
+	apOnuDB *onuDeviceDB, aTechProfileID uint16, aRequestEvent OnuDeviceEvent, aName string,
+	aDeviceID string, aCommChannel chan Message) *uniPonAniConfigFsm {
+	instFsm := &uniPonAniConfigFsm{
+		pOmciCC:            apDevOmciCC,
+		pOnuUniPort:        apUniPort,
+		pUniTechProf:       apUniTechProf,
+		pOnuDB:             apOnuDB,
+		techProfileID:      aTechProfileID,
+		requestEvent:       aRequestEvent,
+		aniConfigCompleted: false,
+		chanSet:            false,
+	}
+	instFsm.pAdaptFsm = NewAdapterFsm(aName, aDeviceID, aCommChannel)
+	if instFsm.pAdaptFsm == nil {
+		logger.Errorw("uniPonAniConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
+			"device-id": aDeviceID})
+		return nil
+	}
+
+	instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
+		aniStDisabled,
+		fsm.Events{
+
+			{Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
+
+			//Note: .1p-Mapper and MBPCD might also have multi instances (per T-Cont) - by now only one 1 T-Cont considered!
+			{Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
+			{Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
+			{Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
+			{Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
+			// the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
+			{Name: aniEvRxGemntcpsResp, Src: []string{aniStCreatingGemNCTPs}, Dst: aniStCreatingGemIWs},
+			// the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
+			{Name: aniEvRxGemiwsResp, Src: []string{aniStCreatingGemIWs}, Dst: aniStSettingPQs},
+			// the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
+			{Name: aniEvRxPrioqsResp, Src: []string{aniStSettingPQs}, Dst: aniStSettingDot1PMapper},
+			{Name: aniEvRxDot1pmapSResp, Src: []string{aniStSettingDot1PMapper}, Dst: aniStConfigDone},
+
+			{Name: aniEvTimeoutSimple, Src: []string{
+				aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper}, Dst: aniStStarting},
+			{Name: aniEvTimeoutMids, Src: []string{
+				aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
+
+			// exceptional treatment for all states except aniStResetting
+			{Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
+				aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
+				aniStConfigDone}, Dst: aniStResetting},
+			// the only way to get to resource-cleared disabled state again is via "resseting"
+			{Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
+		},
+
+		fsm.Callbacks{
+			"enter_state":                         func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
+			("enter_" + aniStStarting):            func(e *fsm.Event) { instFsm.enterConfigStartingState(e) },
+			("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(e) },
+			("enter_" + aniStCreatingMBPCD):       func(e *fsm.Event) { instFsm.enterCreatingMBPCD(e) },
+			("enter_" + aniStSettingTconts):       func(e *fsm.Event) { instFsm.enterSettingTconts(e) },
+			("enter_" + aniStCreatingGemNCTPs):    func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(e) },
+			("enter_" + aniStCreatingGemIWs):      func(e *fsm.Event) { instFsm.enterCreatingGemIWs(e) },
+			("enter_" + aniStSettingPQs):          func(e *fsm.Event) { instFsm.enterSettingPQs(e) },
+			("enter_" + aniStSettingDot1PMapper):  func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(e) },
+			("enter_" + aniStConfigDone):          func(e *fsm.Event) { instFsm.enterAniConfigDone(e) },
+			("enter_" + aniStResetting):           func(e *fsm.Event) { instFsm.enterResettingState(e) },
+			("enter_" + aniStDisabled):            func(e *fsm.Event) { instFsm.enterDisabledState(e) },
+		},
+	)
+	if instFsm.pAdaptFsm.pFsm == nil {
+		logger.Errorw("uniPonAniConfigFsm's Base FSM could not be instantiated!!", log.Fields{
+			"device-id": aDeviceID})
+		return nil
+	}
+
+	logger.Infow("uniPonAniConfigFsm created", log.Fields{"device-id": aDeviceID})
+	return instFsm
+}
+
+//setFsmCompleteChannel sets the requested channel and channel result for transfer on success
+func (oFsm *uniPonAniConfigFsm) setFsmCompleteChannel(aChSuccess chan<- uint8, aProcStep uint8) {
+	oFsm.chSuccess = aChSuccess
+	oFsm.procStep = aProcStep
+	oFsm.chanSet = true
+}
+
+func (oFsm *uniPonAniConfigFsm) prepareAndEnterConfigState(aPAFsm *AdapterFsm) {
+	if aPAFsm != nil && aPAFsm.pFsm != nil {
+		//stick to pythonAdapter numbering scheme
+		//index 0 in naming refers to possible usage of multiple instances (later)
+		oFsm.mapperSP0ID = ieeeMapperServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) + oFsm.techProfileID
+		oFsm.macBPCD0ID = macBridgePortAniEID + uint16(oFsm.pOnuUniPort.entityID) + oFsm.techProfileID
+
+		// For the time being: if there are multiple T-Conts on the ONU the first one from the entityID-ordered list is used
+		// TODO!: if more T-Conts have to be supported (tcontXID!), then use the first instances of the entity-ordered list
+		// or use the py code approach, which might be a bit more complicated, but also more secure, as it
+		// ensures that the selected T-Cont also has queues (which I would assume per definition from ONU, but who knows ...)
+		// so this approach would search the (sorted) upstream PrioQueue list and use the T-Cont (if available) from highest Bytes
+		// or sndHighByte of relatedPort Attribute (T-Cont Reference) and in case of multiple TConts find the next free TContIndex
+		// that way from PrioQueue.relatedPort list
+		if tcontInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.TContClassID); len(tcontInstKeys) > 0 {
+			oFsm.tcont0ID = tcontInstKeys[0]
+			logger.Debugw("Used TcontId:", log.Fields{"TcontId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
+				"device-id": oFsm.pAdaptFsm.deviceID})
+		} else {
+			logger.Warnw("No TCont instances found", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+		}
+		oFsm.alloc0ID = (*(oFsm.pUniTechProf.mapPonAniConfig[oFsm.pOnuUniPort.uniID]))[0].tcontParams.allocID
+		loGemPortAttribs := ponAniGemPortAttribs{}
+		//for all TechProfile set GemIndices
+		for _, gemEntry := range (*(oFsm.pUniTechProf.mapPonAniConfig[oFsm.pOnuUniPort.uniID]))[0].mapGemPortParams {
+			//collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
+
+			if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.PriorityQueueClassID); len(queueInstKeys) > 0 {
+
+				loGemPortAttribs.gemPortID = gemEntry.gemPortID
+				// MibDb usage: upstream PrioQueue.RelatedPort = xxxxyyyy with xxxx=TCont.Entity(incl. slot) and yyyy=prio
+				// i.e.: search PrioQueue list with xxxx=actual T-Cont.Entity,
+				// from that list use the PrioQueue.Entity with  gemEntry.prioQueueIndex == yyyy (expect 0..7)
+				usQrelPortMask := uint32((((uint32)(oFsm.tcont0ID)) << 16) + uint32(gemEntry.prioQueueIndex))
+
+				// MibDb usage: downstream PrioQueue.RelatedPort = xxyyzzzz with xx=slot, yy=UniPort and zzzz=prio
+				// i.e.: search PrioQueue list with yy=actual pOnuUniPort.uniID,
+				// from that list use the PrioQueue.Entity with gemEntry.prioQueueIndex == zzzz (expect 0..7)
+				// Note: As we do not maintain any slot numbering, slot number will be excluded from seatch pattern.
+				//       Furthermore OMCI Onu port-Id is expected to start with 1 (not 0).
+				dsQrelPortMask := uint32((((uint32)(oFsm.pOnuUniPort.uniID + 1)) << 16) + uint32(gemEntry.prioQueueIndex))
+
+				usQueueFound := false
+				dsQueueFound := false
+				for _, mgmtEntityID := range queueInstKeys {
+					if meAttributes := oFsm.pOnuDB.GetMe(me.PriorityQueueClassID, mgmtEntityID); meAttributes != nil {
+						returnVal := meAttributes["RelatedPort"]
+						if returnVal != nil {
+							if relatedPort, err := oFsm.pOnuDB.getUint32Attrib(returnVal); err == nil {
+								if relatedPort == usQrelPortMask {
+									loGemPortAttribs.upQueueID = mgmtEntityID
+									logger.Debugw("UpQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
+										"upQueueID": strconv.FormatInt(int64(loGemPortAttribs.upQueueID), 16), "device-id": oFsm.pAdaptFsm.deviceID})
+									usQueueFound = true
+								} else if (relatedPort&0xFFFFFF) == dsQrelPortMask && mgmtEntityID < 0x8000 {
+									loGemPortAttribs.downQueueID = mgmtEntityID
+									logger.Debugw("DownQueue for GemPort found:", log.Fields{"gemPortID": loGemPortAttribs.gemPortID,
+										"downQueueID": strconv.FormatInt(int64(loGemPortAttribs.downQueueID), 16), "device-id": oFsm.pAdaptFsm.deviceID})
+									dsQueueFound = true
+								}
+								if usQueueFound && dsQueueFound {
+									break
+								}
+							} else {
+								logger.Warnw("Could not convert attribute value", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+							}
+						} else {
+							logger.Warnw("'RelatedPort' not found in meAttributes:", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+						}
+					} else {
+						logger.Warnw("No attributes available in DB:", log.Fields{"meClassID": me.PriorityQueueClassID,
+							"mgmtEntityID": mgmtEntityID, "device-id": oFsm.pAdaptFsm.deviceID})
+					}
+				}
+			} else {
+				logger.Warnw("No PriorityQueue instances found", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+			}
+			loGemPortAttribs.direction = gemEntry.direction
+			loGemPortAttribs.qosPolicy = gemEntry.queueSchedPolicy
+			loGemPortAttribs.weight = gemEntry.queueWeight
+			loGemPortAttribs.pbitString = gemEntry.pbitString
+
+			logger.Debugw("prio-related GemPort attributes:", log.Fields{
+				"gemPortID":      loGemPortAttribs.gemPortID,
+				"upQueueID":      loGemPortAttribs.upQueueID,
+				"downQueueID":    loGemPortAttribs.downQueueID,
+				"pbitString":     loGemPortAttribs.pbitString,
+				"prioQueueIndex": gemEntry.prioQueueIndex,
+			})
+
+			oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
+		}
+		_ = aPAFsm.pFsm.Event(aniEvStartConfig)
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) enterConfigStartingState(e *fsm.Event) {
+	logger.Debugw("UniPonAniConfigFsm start", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.pAdaptFsm.deviceID})
+	if oFsm.omciMIdsResponseReceived == nil {
+		oFsm.omciMIdsResponseReceived = make(chan bool)
+		logger.Debug("uniPonAniConfigFsm - OMCI multiInstance RxChannel defined")
+	} else {
+		// as we may 're-use' this instance of FSM and the connected channel
+		// make sure there is no 'lingering' request in the already existing channel:
+		// (simple loop sufficient as we are the only receiver)
+		for len(oFsm.omciMIdsResponseReceived) > 0 {
+			<-oFsm.omciMIdsResponseReceived
+		}
+	}
+	oFsm.gemPortAttribsSlice = nil
+
+	go oFsm.processOmciAniMessages()
+
+	pConfigAniStateAFsm := oFsm.pAdaptFsm
+	if pConfigAniStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go oFsm.prepareAndEnterConfigState(pConfigAniStateAFsm)
+
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) enterCreatingDot1PMapper(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm Tx Create::Dot1PMapper", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
+		"in state":  e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	meInstance := oFsm.pOmciCC.sendCreateDot1PMapper(context.TODO(), ConstDefaultOmciTimeout, true,
+		oFsm.mapperSP0ID, oFsm.pAdaptFsm.commChan)
+	oFsm.pOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *uniPonAniConfigFsm) enterCreatingMBPCD(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm Tx Create::MBPCD", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
+		"TPPtr":     strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
+		"in state":  e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	bridgePtr := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo) //cmp also omci_cc.go::sendCreateMBServiceProfile
+	meParams := me.ParamData{
+		EntityID: oFsm.macBPCD0ID,
+		Attributes: me.AttributeValueMap{
+			"BridgeIdPointer": bridgePtr,
+			"PortNum":         0xFF, //fixed unique ANI side indication
+			"TpType":          3,    //for .1PMapper
+			"TpPointer":       oFsm.mapperSP0ID,
+		},
+	}
+	meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
+		oFsm.pAdaptFsm.commChan, meParams)
+	oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+}
+
+func (oFsm *uniPonAniConfigFsm) enterSettingTconts(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm Tx Set::Tcont", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.tcont0ID), 16),
+		"AllocId":   strconv.FormatInt(int64(oFsm.alloc0ID), 16),
+		"in state":  e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	meParams := me.ParamData{
+		EntityID: oFsm.tcont0ID,
+		Attributes: me.AttributeValueMap{
+			"AllocId": oFsm.alloc0ID,
+		},
+	}
+	meInstance := oFsm.pOmciCC.sendSetTcontVar(context.TODO(), ConstDefaultOmciTimeout, true,
+		oFsm.pAdaptFsm.commChan, meParams)
+	oFsm.pOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *uniPonAniConfigFsm) enterCreatingGemNCTPs(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm - start creating GemNWCtp loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	go oFsm.performCreatingGemNCTPs()
+}
+
+func (oFsm *uniPonAniConfigFsm) enterCreatingGemIWs(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm - start creating GemIwTP loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	go oFsm.performCreatingGemIWs()
+}
+
+func (oFsm *uniPonAniConfigFsm) enterSettingPQs(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm - start setting PrioQueue loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	go oFsm.performSettingPQs()
+}
+
+func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
+		"toGemIw": 1024 /* cmp above */, "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+
+	logger.Debugw("uniPonAniConfigFsm Tx Set::1pMapper", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
+		"in state":  e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+
+	meParams := me.ParamData{
+		EntityID:   oFsm.mapperSP0ID,
+		Attributes: make(me.AttributeValueMap),
+	}
+
+	var loPrioGemPortArray [8]uint16
+	for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
+		for i := 0; i < 8; i++ {
+			// "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
+			if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
+				if prio == 1 { // Check this p-bit is set
+					if loPrioGemPortArray[i] == 0 {
+						loPrioGemPortArray[i] = gemPortAttribs.gemPortID //gemPortId=EntityID and unique
+					} else {
+						logger.Warnw("uniPonAniConfigFsm PrioString not unique", log.Fields{
+							"device-id": oFsm.pAdaptFsm.deviceID, "IgnoredGemPort": gemPortAttribs.gemPortID,
+							"SetGemPort": loPrioGemPortArray[i]})
+					}
+				}
+			} else {
+				logger.Warnw("uniPonAniConfigFsm PrioString evaluation error", log.Fields{
+					"device-id": oFsm.pAdaptFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
+					"prioString": gemPortAttribs.pbitString, "position": i})
+			}
+
+		}
+	}
+	var foundIwPtr bool = false
+	for index, value := range loPrioGemPortArray {
+		if value != 0 {
+			foundIwPtr = true
+			meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
+			logger.Debugf("UniPonAniConfigFsm Set::1pMapper", log.Fields{
+				"IwPtr for Prio%d": strconv.FormatInt(int64(value), 16), "device-id": oFsm.pAdaptFsm.deviceID}, index)
+			meParams.Attributes[meAttribute] = value
+
+		}
+	}
+
+	if !foundIwPtr {
+		logger.Errorw("UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
+			"device-id": oFsm.pAdaptFsm.deviceID})
+		//let's reset the state machine in order to release all resources now
+		pConfigAniStateAFsm := oFsm.pAdaptFsm
+		if pConfigAniStateAFsm != nil {
+			// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+			go func(aPAFsm *AdapterFsm) {
+				if aPAFsm != nil && aPAFsm.pFsm != nil {
+					_ = aPAFsm.pFsm.Event(aniEvReset)
+				}
+			}(pConfigAniStateAFsm)
+		}
+	}
+
+	meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
+		oFsm.pAdaptFsm.commChan, meParams)
+	oFsm.pOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(e *fsm.Event) {
+
+	oFsm.aniConfigCompleted = true
+
+	pConfigAniStateAFsm := oFsm.pAdaptFsm
+	if pConfigAniStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(aPAFsm *AdapterFsm) {
+			if aPAFsm != nil && aPAFsm.pFsm != nil {
+				_ = aPAFsm.pFsm.Event(aniEvReset)
+			}
+		}(pConfigAniStateAFsm)
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) enterResettingState(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm resetting", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+
+	pConfigAniStateAFsm := oFsm.pAdaptFsm
+	if pConfigAniStateAFsm != nil {
+		// abort running message processing
+		fsmAbortMsg := Message{
+			Type: TestMsg,
+			Data: TestMessage{
+				TestMessageVal: AbortMessageProcessing,
+			},
+		}
+		pConfigAniStateAFsm.commChan <- fsmAbortMsg
+
+		//try to restart the FSM to 'disabled', decouple event transfer
+		go func(aPAFsm *AdapterFsm) {
+			if aPAFsm != nil && aPAFsm.pFsm != nil {
+				_ = aPAFsm.pFsm.Event(aniEvRestart)
+			}
+		}(pConfigAniStateAFsm)
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) enterDisabledState(e *fsm.Event) {
+	logger.Debugw("uniPonAniConfigFsm enters disabled state", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+
+	if oFsm.aniConfigCompleted {
+		logger.Debugw("uniPonAniConfigFsm send dh event notification", log.Fields{
+			"from_State": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+		//use DeviceHandler event notification directly
+		oFsm.pOmciCC.pBaseDeviceHandler.deviceProcStatusUpdate(oFsm.requestEvent)
+		oFsm.aniConfigCompleted = false
+	}
+	oFsm.pUniTechProf.setConfigDone(oFsm.pOnuUniPort.uniID, true)
+	go oFsm.pOmciCC.pBaseDeviceHandler.verifyUniVlanConfigRequest(oFsm.pOnuUniPort)
+
+	if oFsm.chanSet {
+		// indicate processing done to the caller
+		logger.Debugw("uniPonAniConfigFsm processingDone on channel", log.Fields{
+			"ProcessingStep": oFsm.procStep, "from_State": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+		oFsm.chSuccess <- oFsm.procStep
+		oFsm.chanSet = false //reset the internal channel state
+	}
+
+}
+
+func (oFsm *uniPonAniConfigFsm) processOmciAniMessages( /*ctx context.Context*/ ) {
+	logger.Debugw("Start uniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+loop:
+	for {
+		// case <-ctx.Done():
+		// 	logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.pAdaptFsm.deviceID})
+		// 	break loop
+		message, ok := <-oFsm.pAdaptFsm.commChan
+		if !ok {
+			logger.Info("UniPonAniConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+			// but then we have to ensure a restart of the FSM as well - as exceptional procedure
+			_ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+			break loop
+		}
+		logger.Debugw("UniPonAniConfigFsm Rx Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+
+		switch message.Type {
+		case TestMsg:
+			msg, _ := message.Data.(TestMessage)
+			if msg.TestMessageVal == AbortMessageProcessing {
+				logger.Infow("UniPonAniConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+				break loop
+			}
+			logger.Warnw("UniPonAniConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "MessageVal": msg.TestMessageVal})
+		case OMCI:
+			msg, _ := message.Data.(OmciMessage)
+			oFsm.handleOmciAniConfigMessage(msg)
+		default:
+			logger.Warn("UniPonAniConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
+				"message.Type": message.Type})
+		}
+
+	}
+	logger.Infow("End uniPonAniConfigFsm Msg processing", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+}
+
+func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigCreateResponseMessage(msg OmciMessage) {
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
+	if msgLayer == nil {
+		logger.Error("Omci Msg layer could not be detected for CreateResponse")
+		return
+	}
+	msgObj, msgOk := msgLayer.(*omci.CreateResponse)
+	if !msgOk {
+		logger.Error("Omci Msg layer could not be assigned for CreateResponse")
+		return
+	}
+	logger.Debugw("CreateResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
+	if msgObj.Result != me.Success {
+		logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+		// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+		return
+	}
+	if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
+		msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
+		// maybe we can use just the same eventName for different state transitions like "forward"
+		//   - might be checked, but so far I go for sure and have to inspect the concrete state events ...
+		switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
+		case "Ieee8021PMapperServiceProfile":
+			{ // let the FSM proceed ...
+				_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapCResp)
+			}
+		case "MacBridgePortConfigurationData":
+			{ // let the FSM proceed ...
+				_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
+			}
+		case "GemPortNetworkCtp", "GemInterworkingTerminationPoint":
+			{ // let aniConfig Multi-Id processing proceed by stopping the wait function
+				oFsm.omciMIdsResponseReceived <- true
+			}
+		}
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigSetResponseMessage(msg OmciMessage) {
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
+	if msgLayer == nil {
+		logger.Error("UniPonAniConfigFsm - Omci Msg layer could not be detected for SetResponse")
+		return
+	}
+	msgObj, msgOk := msgLayer.(*omci.SetResponse)
+	if !msgOk {
+		logger.Error("UniPonAniConfigFsm - Omci Msg layer could not be assigned for SetResponse")
+		return
+	}
+	logger.Debugw("UniPonAniConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
+	if msgObj.Result != me.Success {
+		logger.Errorw("UniPonAniConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+		// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+		return
+	}
+	if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
+		msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
+		//store the created ME into DB //TODO??? obviously the Python code does not store the config ...
+		// if, then something like:
+		//oFsm.pOnuDB.StoreMe(msgObj)
+
+		switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
+		case "TCont":
+			{ // let the FSM proceed ...
+				_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxTcontsResp)
+			}
+		case "PriorityQueue":
+			{ // let the PrioQueue init proceed by stopping the wait function
+				oFsm.omciMIdsResponseReceived <- true
+			}
+		case "Ieee8021PMapperServiceProfile":
+			{ // let the FSM proceed ...
+				_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
+			}
+		}
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) handleOmciAniConfigMessage(msg OmciMessage) {
+	logger.Debugw("Rx OMCI UniPonAniConfigFsm Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
+		"msgType": msg.OmciMsg.MessageType})
+
+	switch msg.OmciMsg.MessageType {
+	case omci.CreateResponseType:
+		{
+			oFsm.handleOmciAniConfigCreateResponseMessage(msg)
+
+		} //CreateResponseType
+	case omci.SetResponseType:
+		{
+			oFsm.handleOmciAniConfigSetResponseMessage(msg)
+
+		} //SetResponseType
+	default:
+		{
+			logger.Errorw("uniPonAniConfigFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
+			return
+		}
+	}
+}
+
+func (oFsm *uniPonAniConfigFsm) performCreatingGemNCTPs() {
+	for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
+		logger.Debugw("uniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
+			"EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
+			"TcontId":   strconv.FormatInt(int64(oFsm.tcont0ID), 16),
+			"device-id": oFsm.pAdaptFsm.deviceID})
+		meParams := me.ParamData{
+			EntityID: gemPortAttribs.gemPortID, //unique, same as PortId
+			Attributes: me.AttributeValueMap{
+				"PortId":       gemPortAttribs.gemPortID,
+				"TContPointer": oFsm.tcont0ID,
+				"Direction":    gemPortAttribs.direction,
+				//ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
+				//  TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
+				"TrafficManagementPointerForUpstream": gemPortAttribs.upQueueID, //might be different in wrr-only Setup - tcont0ID
+				"PriorityQueuePointerForDownStream":   gemPortAttribs.downQueueID,
+			},
+		}
+		meInstance := oFsm.pOmciCC.sendCreateGemNCTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
+			oFsm.pAdaptFsm.commChan, meParams)
+		//accept also nil as (error) return value for writing to LastTx
+		//  - this avoids misinterpretation of new received OMCI messages
+		oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+		//verify response
+		err := oFsm.waitforOmciResponse()
+		if err != nil {
+			logger.Errorw("GemNWCtp create failed, aborting AniConfig FSM!",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "GemIndex": gemIndex})
+			_ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+			return
+		}
+	} //for all GemPorts of this T-Cont
+
+	logger.Debugw("GemNWCtp create loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemntcpsResp)
+}
+
+func (oFsm *uniPonAniConfigFsm) performCreatingGemIWs() {
+	for gemIndex, gemPortAttribs := range oFsm.gemPortAttribsSlice {
+		logger.Debugw("uniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
+			"EntitytId": strconv.FormatInt(int64(gemPortAttribs.gemPortID), 16),
+			"SPPtr":     strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
+			"device-id": oFsm.pAdaptFsm.deviceID})
+		meParams := me.ParamData{
+			EntityID: gemPortAttribs.gemPortID,
+			Attributes: me.AttributeValueMap{
+				"GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID, //same as EntityID, see above
+				"InterworkingOption":                   5,                        //fixed model:: G.998 .1pMapper
+				"ServiceProfilePointer":                oFsm.mapperSP0ID,
+				"InterworkingTerminationPointPointer":  0, //not used with .1PMapper Mac bridge
+				"GalProfilePointer":                    galEthernetEID,
+			},
+		}
+		meInstance := oFsm.pOmciCC.sendCreateGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout, true,
+			oFsm.pAdaptFsm.commChan, meParams)
+		//accept also nil as (error) return value for writing to LastTx
+		//  - this avoids misinterpretation of new received OMCI messages
+		oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+		//verify response
+		err := oFsm.waitforOmciResponse()
+		if err != nil {
+			logger.Errorw("GemIwTp create failed, aborting AniConfig FSM!",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "GemIndex": gemIndex})
+			_ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+			return
+		}
+	} //for all GemPort's of this T-Cont
+
+	logger.Debugw("GemIwTp create loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxGemiwsResp)
+}
+
+func (oFsm *uniPonAniConfigFsm) performSettingPQs() {
+	const cu16StrictPrioWeight uint16 = 0xFFFF
+	loQueueMap := ordered_map.NewOrderedMap()
+	for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
+		if gemPortAttribs.qosPolicy == "WRR" {
+			if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
+				//key does not yet exist
+				loQueueMap.Set(gemPortAttribs.upQueueID, uint16(gemPortAttribs.weight))
+			}
+		} else {
+			loQueueMap.Set(gemPortAttribs.upQueueID, cu16StrictPrioWeight) //use invalid weight value to indicate SP
+		}
+	}
+
+
+	loTrafficSchedulerEID := 0x8000
+	iter := loQueueMap.IterFunc()
+	for kv, ok := iter(); ok; kv, ok = iter() {
+		queueIndex := (kv.Key).(uint16)
+		meParams := me.ParamData{
+			EntityID:   queueIndex,
+			Attributes: make(me.AttributeValueMap),
+		}
+		if (kv.Value).(uint16) == cu16StrictPrioWeight {
+			//StrictPrio indication
+			logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to StrictPrio", log.Fields{
+				"EntitytId": strconv.FormatInt(int64(queueIndex), 16),
+				"device-id": oFsm.pAdaptFsm.deviceID})
+			meParams.Attributes["TrafficSchedulerPointer"] = 0 //ensure T-Cont defined StrictPrio scheduling
+		} else {
+			//WRR indication
+			logger.Debugw("uniPonAniConfigFsm Tx Set::PrioQueue to WRR", log.Fields{
+				"EntitytId": strconv.FormatInt(int64(queueIndex), 16),
+				"Weight":    kv.Value,
+				"device-id": oFsm.pAdaptFsm.deviceID})
+			meParams.Attributes["TrafficSchedulerPointer"] = loTrafficSchedulerEID //ensure assignment of the relevant trafficScheduler
+			meParams.Attributes["Weight"] = uint8(kv.Value.(uint16))
+		}
+		meInstance := oFsm.pOmciCC.sendSetPrioQueueVar(context.TODO(), ConstDefaultOmciTimeout, true,
+			oFsm.pAdaptFsm.commChan, meParams)
+		//accept also nil as (error) return value for writing to LastTx
+		//  - this avoids misinterpretation of new received OMCI messages
+		oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+		//verify response
+		err := oFsm.waitforOmciResponse()
+		if err != nil {
+			logger.Errorw("PrioQueue set failed, aborting AniConfig FSM!",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "QueueId": strconv.FormatInt(int64(queueIndex), 16)})
+			_ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+			return
+		}
+
+		//TODO: In case of WRR setting of the GemPort/PrioQueue it might further be necessary to
+		//  write the assigned trafficScheduler with the requested Prio to be considered in the StrictPrio scheduling
+		//  of the (next upstream) assigned T-Cont, which is f(prioQueue[priority]) - in relation to other SP prioQueues
+		//  not yet done because of BBSIM TrafficScheduler issues (and not done in py code as well)
+
+	} //for all upstream prioQueues
+
+	logger.Debugw("PrioQueue set loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxPrioqsResp)
+}
+
+func (oFsm *uniPonAniConfigFsm) waitforOmciResponse() error {
+	select {
+	case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw("UniPonAniConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+		return errors.New("uniPonAniConfigFsm multi entity timeout")
+	case success := <-oFsm.omciMIdsResponseReceived:
+		if success {
+			logger.Debug("uniPonAniConfigFsm multi entity response received")
+			return nil
+		}
+		// should not happen so far
+		logger.Warnw("uniPonAniConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+		return errors.New("uniPonAniConfigFsm multi entity responseError")
+	}
+}
diff --git a/internal/pkg/onuadaptercore/omci_cc.go b/internal/pkg/onuadaptercore/omci_cc.go
new file mode 100644
index 0000000..9cf38ac
--- /dev/null
+++ b/internal/pkg/onuadaptercore/omci_cc.go
@@ -0,0 +1,1452 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"container/list"
+	"context"
+	"encoding/binary"
+	"encoding/hex"
+	"errors"
+	"strconv"
+	"sync"
+
+
+	"github.com/google/gopacket"
+	gp "github.com/google/gopacket"
+
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+)
+
+// ### OMCI related definitions - retrieved from Python adapter code/trace ####
+
+//ConstDefaultOmciTimeout - Default OMCI Timeout
+const ConstDefaultOmciTimeout = 10 // ( 3 ?) Seconds
+
+const galEthernetEID = uint16(1)
+const maxGemPayloadSize = uint16(48)
+const connectivityModeValue = uint8(5)
+
+//const defaultTPID = uint16(0x8100)
+//const broadComDefaultVID = uint16(4091)
+const macBridgeServiceProfileEID = uint16(0x201) // TODO: most all these need better definition or tuning
+const ieeeMapperServiceProfileEID = uint16(0x8001)
+const macBridgePortAniEID = uint16(0x2102)
+
+// ### OMCI related definitions - end
+
+//callbackPairEntry to be used for OMCI send/receive correlation
+type callbackPairEntry struct {
+	cbRespChannel chan Message
+	cbFunction    func(*omci.OMCI, *gp.Packet, chan Message) error
+}
+
+//callbackPair to be used for ReceiveCallback init
+type callbackPair struct {
+	cbKey   uint16
+	cbEntry callbackPairEntry
+}
+
+type omciTransferStructure struct {
+	txFrame  []byte
+	timeout  int
+	retry    int
+	highPrio bool
+}
+
+//omciCC structure holds information needed for OMCI communication (to/from OLT Adapter)
+type omciCC struct {
+	enabled            bool
+	pOnuDeviceEntry    *OnuDeviceEntry
+	deviceID           string
+	pBaseDeviceHandler *deviceHandler
+	coreProxy          adapterif.CoreProxy
+	adapterProxy       adapterif.AdapterProxy
+	supportExtMsg      bool
+	txFrames, txOnuFrames                uint32
+	rxFrames, rxOnuFrames, rxOnuDiscards uint32
+
+	mutexTid       sync.Mutex
+	tid            uint16
+	mutexHpTid     sync.Mutex
+	hpTid          uint16
+	uploadSequNo   uint16
+	uploadNoOfCmds uint16
+
+	mutexTxQueue      sync.Mutex
+	txQueue           *list.List
+	mutexRxSchedMap   sync.Mutex
+	rxSchedulerMap    map[uint16]callbackPairEntry
+	pLastTxMeInstance *me.ManagedEntity
+}
+
+//newOmciCC constructor returns a new instance of a OmciCC
+//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
+func newOmciCC(ctx context.Context, onuDeviceEntry *OnuDeviceEntry,
+	deviceID string, deviceHandler *deviceHandler,
+	coreProxy adapterif.CoreProxy, adapterProxy adapterif.AdapterProxy) *omciCC {
+	logger.Infow("init-omciCC", log.Fields{"device-id": deviceID})
+	var omciCC omciCC
+	omciCC.enabled = false
+	omciCC.pOnuDeviceEntry = onuDeviceEntry
+	omciCC.deviceID = deviceID
+	omciCC.pBaseDeviceHandler = deviceHandler
+	omciCC.coreProxy = coreProxy
+	omciCC.adapterProxy = adapterProxy
+	omciCC.supportExtMsg = false
+	omciCC.txFrames = 0
+	omciCC.txOnuFrames = 0
+	omciCC.rxFrames = 0
+	omciCC.rxOnuFrames = 0
+	omciCC.rxOnuDiscards = 0
+	omciCC.tid = 0x1
+	omciCC.hpTid = 0x8000
+	omciCC.uploadSequNo = 0
+	omciCC.uploadNoOfCmds = 0
+
+	omciCC.txQueue = list.New()
+	omciCC.rxSchedulerMap = make(map[uint16]callbackPairEntry)
+
+	return &omciCC
+}
+
+// Rx handler for omci messages
+func (oo *omciCC) receiveOnuMessage(ctx context.Context, omciMsg *omci.OMCI) error {
+	logger.Debugw("rx-onu-autonomous-message", log.Fields{"omciMsgType": omciMsg.MessageType,
+		"payload": hex.EncodeToString(omciMsg.Payload)})
+	/*
+			msgType = rxFrame.fields["message_type"] //assumed OmciOperationsValue
+			rxOnuFrames++
+
+			switch msgType {
+			case AlarmNotification:
+				{
+					logger.Info("Unhandled: received-onu-alarm-message")
+					// python code was:
+					//if msg_type == EntityOperations.AlarmNotification.value:
+					//	topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Alarm_Notification)
+					//	self.reactor.callLater(0,  self.event_bus.publish, topic, msg)
+					//
+					return errors.New("RxAlarmNotification unimplemented")
+				}
+			case AttributeValueChange:
+				{
+					logger.Info("Unhandled: received-attribute-value-change")
+					// python code was:
+					//elif msg_type == EntityOperations.AttributeValueChange.value:
+					//	topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.AVC_Notification)
+					//	self.reactor.callLater(0,  self.event_bus.publish, topic, msg)
+					//
+					return errors.New("RxAttributeValueChange unimplemented")
+				}
+			case TestResult:
+				{
+					logger.Info("Unhandled: received-test-result")
+					// python code was:
+					//elif msg_type == EntityOperations.TestResult.value:
+					//	topic = OMCI_CC.event_bus_topic(self._device_id, RxEvent.Test_Result)
+					//	self.reactor.callLater(0,  self.event_bus.publish, topic, msg)
+					//
+					return errors.New("RxTestResult unimplemented")
+				}
+			default:
+				{
+					logger.Errorw("rx-onu-unsupported-autonomous-message", log.Fields{"msgType": msgType})
+					rxOnuDiscards++
+					return errors.New("RxOnuMsgType unimplemented")
+				}
+		    }
+	*/
+	return errors.New("receiveOnuMessage unimplemented")
+}
+
+// Rx handler for onu messages
+//    e.g. would call ReceiveOnuMessage() in case of TID=0 or Action=test ...
+func (oo *omciCC) receiveMessage(ctx context.Context, rxMsg []byte) error {
+	if len(rxMsg) >= 44 { // then it should normally include the BaseFormat trailer Len
+		// NOTE: autocorrection only valid for OmciBaseFormat, which is not specifically verified here!!!
+		//  (am extendedFormat message could be destroyed this way!)
+		trailerLenData := rxMsg[42:44]
+		trailerLen := binary.BigEndian.Uint16(trailerLenData)
+		//logger.Debugw("omci-received-trailer-len", log.Fields{"Length": trailerLen})
+		if trailerLen != 40 { // invalid base Format entry -> autocorrect
+			binary.BigEndian.PutUint16(rxMsg[42:44], 40)
+			logger.Debug("cc-corrected-omci-message: trailer len inserted")
+		}
+	} else {
+		logger.Errorw("received omci-message too small for OmciBaseFormat - abort", log.Fields{"Length": len(rxMsg)})
+		return errors.New("rxOmciMessage too small for BaseFormat")
+	}
+
+	packet := gopacket.NewPacket(rxMsg, omci.LayerTypeOMCI, gopacket.NoCopy)
+	if packet == nil {
+		logger.Error("omci-message could not be decoded")
+		return errors.New("could not decode rxMsg as OMCI")
+	}
+	omciLayer := packet.Layer(omci.LayerTypeOMCI)
+	if omciLayer == nil {
+		logger.Error("omci-message could not decode omci layer")
+		return errors.New("could not decode omci layer")
+	}
+	omciMsg, ok := omciLayer.(*omci.OMCI)
+	if !ok {
+		logger.Error("omci-message could not assign omci layer")
+		return errors.New("could not assign omci layer")
+	}
+	logger.Debugw("omci-message-decoded:", log.Fields{"omciMsgType": omciMsg.MessageType,
+		"transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "DeviceIdent": omciMsg.DeviceIdentifier})
+	if byte(omciMsg.MessageType) & ^me.AK == 0 {
+		// Not a response
+		logger.Debug("RxMsg is no Omci Response Message")
+		if omciMsg.TransactionID == 0 {
+			return oo.receiveOnuMessage(ctx, omciMsg)
+		}
+		logger.Errorw("Unexpected TransCorrId != 0  not accepted for autonomous messages",
+			log.Fields{"msgType": omciMsg.MessageType, "payload": hex.EncodeToString(omciMsg.Payload)})
+		return errors.New("autonomous Omci Message with TranSCorrId != 0 not acccepted")
+
+	}
+	oo.mutexRxSchedMap.Lock()
+	rxCallbackEntry, ok := oo.rxSchedulerMap[omciMsg.TransactionID]
+	if ok && rxCallbackEntry.cbFunction != nil {
+		//disadvantage of decoupling: error verification made difficult, but anyway the question is
+		// how to react on erroneous frame reception, maybe can simply be ignored
+		go rxCallbackEntry.cbFunction(omciMsg, &packet, rxCallbackEntry.cbRespChannel)
+		// having posted the response the request is regarded as 'done'
+		delete(oo.rxSchedulerMap, omciMsg.TransactionID)
+		oo.mutexRxSchedMap.Unlock()
+	} else {
+		oo.mutexRxSchedMap.Unlock()
+		logger.Error("omci-message-response for not registered transCorrId")
+		return errors.New("could not find registered response handler tor transCorrId")
+	}
+
+	return nil
+	/* py code was:
+	           Receive and OMCI message from the proxy channel to the OLT.
+
+	           Call this from your ONU Adapter on a new OMCI Rx on the proxy channel
+	           :param msg: (str) OMCI binary message (used as input to Scapy packet decoder)
+	           """
+	           if not self.enabled:
+	               return
+
+	           try:
+	               now = arrow.utcnow()
+	               d = None
+
+	               # NOTE: Since we may need to do an independent ME map on a per-ONU basis
+	               #       save the current value of the entity_id_to_class_map, then
+	               #       replace it with our custom one before decode, and then finally
+	               #       restore it later. Tried other ways but really made the code messy.
+	               saved_me_map = omci_entities.entity_id_to_class_map
+	               omci_entities.entity_id_to_class_map = self._me_map
+
+	               try:
+	                   rx_frame = msg if isinstance(msg, OmciFrame) else OmciFrame(msg)
+	                   self.logger.debug('recv-omci-msg', omci_msg=hexlify(msg))
+	               except KeyError as e:
+	                   # Unknown, Unsupported, or vendor-specific ME. Key is the unknown classID
+	                   self.logger.debug('frame-decode-key-error', omci_msg=hexlify(msg), e=e)
+	                   rx_frame = self._decode_unknown_me(msg)
+	                   self._rx_unknown_me += 1
+
+	               except Exception as e:
+	                   self.logger.exception('frame-decode', omci_msg=hexlify(msg), e=e)
+	                   return
+
+	               finally:
+	                   omci_entities.entity_id_to_class_map = saved_me_map     # Always restore it.
+
+	               rx_tid = rx_frame.fields['transaction_id']
+	               msg_type = rx_frame.fields['message_type']
+	               self.logger.debug('Received message for rx_tid', rx_tid = rx_tid, msg_type = msg_type)
+	               # Filter the Test Result frame and route through receive onu
+	               # message method.
+	               if rx_tid == 0 or msg_type == EntityOperations.TestResult.value:
+	                   self.logger.debug('Receive ONU message', rx_tid=0)
+	                   return self._receive_onu_message(rx_frame)
+
+	               # Previously unreachable if this is the very first round-trip Rx or we
+	               # have been running consecutive errors
+	               if self._rx_frames == 0 or self._consecutive_errors != 0:
+	                   self.logger.debug('Consecutive errors for rx', err = self._consecutive_errors)
+	                   self.reactor.callLater(0, self._publish_connectivity_event, True)
+
+	               self._rx_frames += 1
+	               self._consecutive_errors = 0
+
+	               try:
+	                   high_priority = self._tid_is_high_priority(rx_tid)
+	                   index = self._get_priority_index(high_priority)
+
+	                   # (timestamp, defer, frame, timeout, retry, delayedCall)
+	                   last_tx_tuple = self._tx_request[index]
+
+	                   if last_tx_tuple is None or \
+	                           last_tx_tuple[OMCI_CC.REQUEST_FRAME].fields.get('transaction_id') != rx_tid:
+	                       # Possible late Rx on a message that timed-out
+	                       if last_tx_tuple:
+	                           self.logger.debug('Unknown message', rx_tid=rx_tid,
+	                                          tx_id=last_tx_tuple[OMCI_CC.REQUEST_FRAME].fields.get('transaction_id'))
+	                       self._rx_unknown_tid += 1
+	                       self._rx_late += 1
+	                       return
+
+	                   ts, d, tx_frame, timeout, retry, dc = last_tx_tuple
+	                   if dc is not None and not dc.cancelled and not dc.called:
+	                       dc.cancel()
+
+	                   _secs = self._update_rx_tx_stats(now, ts)
+
+	                   # Late arrival already serviced by a timeout?
+	                   if d.called:
+	                       self._rx_late += 1
+	                       self.logger.debug('Serviced by timeout. Late arrival', rx_late = self._rx_late)
+	                       return
+
+	               except Exception as e:
+	                   self.logger.exception('frame-match', msg=hexlify(msg), e=e)
+	                   if d is not None:
+	                       return d.errback(failure.Failure(e))
+	                   return
+
+	               # Publish Rx event to listeners in a different task
+	               self.logger.debug('Publish rx event', rx_tid = rx_tid,
+	                              tx_tid = tx_frame.fields['transaction_id'])
+	               reactor.callLater(0, self._publish_rx_frame, tx_frame, rx_frame)
+
+	               # begin success callback chain (will cancel timeout and queue next Tx message)
+	               self._rx_response[index] = rx_frame
+	               d.callback(rx_frame)
+
+	           except Exception as e:
+	   			self.logger.exception('rx-msg', e=e)
+	*/
+}
+
+/*
+func (oo *omciCC) publishRxResponseFrame(ctx context.Context, txFrame []byte, rxFrame []byte) error {
+	return errors.New("publishRxResponseFrame unimplemented")
+		//def _publish_rx_frame(self, tx_frame, rx_frame):
+}
+*/
+
+//Queue the OMCI Frame for a transmit to the ONU via the proxy_channel
+func (oo *omciCC) send(ctx context.Context, txFrame []byte, timeout int, retry int, highPrio bool,
+	receiveCallbackPair callbackPair) error {
+
+	logger.Debugw("register-response-callback:", log.Fields{"for TansCorrId": receiveCallbackPair.cbKey})
+	oo.mutexRxSchedMap.Lock()
+	oo.rxSchedulerMap[receiveCallbackPair.cbKey] = receiveCallbackPair.cbEntry
+	oo.mutexRxSchedMap.Unlock()
+
+	omciTxRequest := omciTransferStructure{
+		txFrame,
+		timeout,
+		retry,
+		highPrio,
+	}
+	oo.mutexTxQueue.Lock()
+	oo.txQueue.PushBack(omciTxRequest) // enqueue
+	oo.mutexTxQueue.Unlock()
+
+	go oo.sendNextRequest(ctx)
+	return nil
+}
+
+//Pull next tx request and send it
+func (oo *omciCC) sendNextRequest(ctx context.Context) error {
+
+	oo.mutexTxQueue.Lock()
+	defer oo.mutexTxQueue.Unlock()
+	for oo.txQueue.Len() > 0 {
+		queueElement := oo.txQueue.Front() // First element
+		omciTxRequest := queueElement.Value.(omciTransferStructure)
+		/* compare olt device handler code:
+		func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) {
+			logger.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 {
+
+				logger.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 {
+					logger.Errorw("onu not found", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId, "error": err})
+					return
+				}
+				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
+				logger.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
+			}
+		*/
+		/* and compare onu_adapter py code:
+		omci_msg = InterAdapterOmciMessage(
+			message=bytes(frame),
+			proxy_address=self._proxy_address,
+			connect_status=self._device.connect_status)
+
+		self.logger.debug('sent-omci-msg', tid=tx_tid, omci_msg=hexlify(bytes(frame)))
+
+		yield self._adapter_proxy.send_inter_adapter_message(
+			msg=omci_msg,
+			type=InterAdapterMessageType.OMCI_REQUEST,
+			from_adapter=self._device.type,
+			to_adapter=self._proxy_address.device_type,
+			to_device_id=self._device_id,
+			proxy_device_id=self._proxy_address.device_id
+		)
+		*/
+		device, err := oo.coreProxy.GetDevice(ctx,
+			oo.pBaseDeviceHandler.deviceID, oo.deviceID) //parent, child
+		if err != nil || device == nil {
+			/*TODO: needs to handle error scenarios */
+			logger.Errorw("Failed to fetch device", log.Fields{"err": err, "ParentId": oo.pBaseDeviceHandler.deviceID,
+				"ChildId": oo.deviceID})
+			return errors.New("failed to fetch device")
+		}
+
+		logger.Debugw("omci-message-sending", log.Fields{"fromDeviceType": oo.pBaseDeviceHandler.DeviceType,
+			"toDeviceType": oo.pBaseDeviceHandler.ProxyAddressType,
+			"onuDeviceID":  oo.deviceID, "proxyDeviceID": oo.pBaseDeviceHandler.ProxyAddressID})
+		logger.Debugw("omci-message-to-send:",
+			log.Fields{"TxOmciMessage": hex.EncodeToString(omciTxRequest.txFrame)})
+
+		omciMsg := &ic.InterAdapterOmciMessage{Message: omciTxRequest.txFrame}
+		if sendErr := oo.adapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
+			ic.InterAdapterMessageType_OMCI_REQUEST,
+			//fromType,toType,toDevId, ProxyDevId
+			oo.pBaseDeviceHandler.DeviceType, oo.pBaseDeviceHandler.ProxyAddressType,
+			oo.deviceID, oo.pBaseDeviceHandler.ProxyAddressID, ""); sendErr != nil {
+			logger.Errorw("send omci request error", log.Fields{"error": sendErr})
+			return sendErr
+		}
+		oo.txQueue.Remove(queueElement) // Dequeue
+	}
+	return nil
+}
+
+func (oo *omciCC) getNextTid(highPriority bool) uint16 {
+	var next uint16
+	if highPriority {
+		oo.mutexTid.Lock()
+		next = oo.hpTid
+		oo.hpTid++
+		if oo.hpTid < 0x8000 {
+			oo.hpTid = 0x8000
+		}
+		oo.mutexTid.Unlock()
+	} else {
+		oo.mutexHpTid.Lock()
+		next = oo.tid
+		oo.tid++
+		if oo.tid >= 0x8000 {
+			oo.tid = 1
+		}
+		oo.mutexHpTid.Unlock()
+	}
+	return next
+}
+
+// ###################################################################################
+// # utility methods provided to work on OMCI messages
+func serialize(msgType omci.MessageType, request gopacket.SerializableLayer, tid uint16) ([]byte, error) {
+	omciLayer := &omci.OMCI{
+		TransactionID: tid,
+		MessageType:   msgType,
+	}
+	return serializeOmciLayer(omciLayer, request)
+}
+
+func serializeOmciLayer(aOmciLayer *omci.OMCI, aRequest gopacket.SerializableLayer) ([]byte, error) {
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
+
+	buffer := gopacket.NewSerializeBuffer()
+	err := gopacket.SerializeLayers(buffer, options, aOmciLayer, aRequest)
+	if err != nil {
+		logger.Errorw("Could not create goPacket Omci serial buffer", log.Fields{"Err": err})
+		return nil, err
+	}
+	return buffer.Bytes(), nil
+}
+
+/*
+func hexEncode(omciPkt []byte) ([]byte, error) {
+	dst := make([]byte, hex.EncodedLen(len(omciPkt)))
+	hex.Encode(dst, omciPkt)
+	return dst, nil
+}
+*/
+
+//supply a response handler for omci response messages to be transferred to the requested FSM
+func (oo *omciCC) receiveOmciResponse(omciMsg *omci.OMCI, packet *gp.Packet, respChan chan Message) error {
+
+	logger.Debugw("omci-message-response - transfer on omciRespChannel", log.Fields{"omciMsgType": omciMsg.MessageType,
+		"transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "device-id": oo.deviceID})
+
+	if oo.pOnuDeviceEntry == nil {
+		logger.Errorw("Abort receiving OMCI response, DeviceEntryPointer is nil", log.Fields{
+			"device-id": oo.deviceID})
+		return errors.New("deviceEntryPointer is nil")
+	}
+
+	omciRespMsg := Message{
+		Type: OMCI,
+		Data: OmciMessage{
+			OmciMsg:    omciMsg,
+			OmciPacket: packet,
+		},
+	}
+	respChan <- omciRespMsg
+
+	return nil
+}
+
+func (oo *omciCC) sendMibReset(ctx context.Context, timeout int, highPrio bool) error {
+
+	logger.Debugw("send MibReset-msg to:", log.Fields{"device-id": oo.deviceID})
+	request := &omci.MibResetRequest{
+		MeBasePacket: omci.MeBasePacket{
+			EntityClass: me.OnuDataClassID,
+		},
+	}
+	tid := oo.getNextTid(highPrio)
+	pkt, err := serialize(omci.MibResetRequestType, request, tid)
+	if err != nil {
+		logger.Errorw("Cannot serialize MibResetRequest", log.Fields{
+			"Err": err, "device-id": oo.deviceID})
+		return err
+	}
+	omciRxCallbackPair := callbackPair{
+		cbKey:   tid,
+		cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
+	}
+	return oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+}
+
+func (oo *omciCC) sendReboot(ctx context.Context, timeout int, highPrio bool, responseChannel chan Message) error {
+	logger.Debugw("send Reboot-msg to:", log.Fields{"device-id": oo.deviceID})
+	request := &omci.RebootRequest{
+		MeBasePacket: omci.MeBasePacket{
+			EntityClass: me.OnuGClassID,
+		},
+	}
+	tid := oo.getNextTid(highPrio)
+	pkt, err := serialize(omci.RebootRequestType, request, tid)
+	if err != nil {
+		logger.Errorw("Cannot serialize RebootRequest", log.Fields{
+			"Err": err, "device-id": oo.deviceID})
+		return err
+	}
+	omciRxCallbackPair := callbackPair{
+		cbKey:   tid,
+		cbEntry: callbackPairEntry{oo.pOnuDeviceEntry.omciRebootMessageReceivedChannel, oo.receiveOmciResponse},
+	}
+
+	err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+	if err != nil {
+		logger.Errorw("Cannot send RebootRequest", log.Fields{
+			"Err": err, "device-id": oo.deviceID})
+		return err
+	}
+	err = oo.pOnuDeviceEntry.waitForRebootResponse(responseChannel)
+	if err != nil {
+		logger.Error("aborting ONU Reboot!")
+		_ = oo.pOnuDeviceEntry.pMibDownloadFsm.pFsm.Event("reset")
+		return err
+	}
+	return nil
+}
+
+func (oo *omciCC) sendMibUpload(ctx context.Context, timeout int, highPrio bool) error {
+	logger.Debugw("send MibUpload-msg to:", log.Fields{"device-id": oo.deviceID})
+	request := &omci.MibUploadRequest{
+		MeBasePacket: omci.MeBasePacket{
+			EntityClass: me.OnuDataClassID,
+		},
+	}
+	tid := oo.getNextTid(highPrio)
+	pkt, err := serialize(omci.MibUploadRequestType, request, tid)
+	if err != nil {
+		logger.Errorw("Cannot serialize MibUploadRequest", log.Fields{
+			"Err": err, "device-id": oo.deviceID})
+		return err
+	}
+	oo.uploadSequNo = 0
+	oo.uploadNoOfCmds = 0
+
+	omciRxCallbackPair := callbackPair{
+		cbKey:   tid,
+		cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
+	}
+	return oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+}
+
+func (oo *omciCC) sendMibUploadNext(ctx context.Context, timeout int, highPrio bool) error {
+	logger.Debugw("send MibUploadNext-msg to:", log.Fields{"device-id": oo.deviceID, "uploadSequNo": oo.uploadSequNo})
+	request := &omci.MibUploadNextRequest{
+		MeBasePacket: omci.MeBasePacket{
+			EntityClass: me.OnuDataClassID,
+		},
+		CommandSequenceNumber: oo.uploadSequNo,
+	}
+	tid := oo.getNextTid(highPrio)
+	pkt, err := serialize(omci.MibUploadNextRequestType, request, tid)
+	if err != nil {
+		logger.Errorw("Cannot serialize MibUploadNextRequest", log.Fields{
+			"Err": err, "device-id": oo.deviceID})
+		return err
+	}
+	oo.uploadSequNo++
+
+	omciRxCallbackPair := callbackPair{
+		cbKey:   tid,
+		cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
+	}
+	return oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+}
+
+func (oo *omciCC) sendCreateGalEthernetProfile(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send GalEnetProfile-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   galEthernetEID,
+		Attributes: me.AttributeValueMap{"MaximumGemPayloadSize": maxGemPayloadSize},
+	}
+	meInstance, omciErr := me.NewGalEthernetProfile(meParams)
+	if omciErr.GetError() == nil {
+		//all setByCreate parameters already set, no default option required ...
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode GalEnetProfileInstance for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize GalEnetProfile create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send GalEnetProfile create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send GalEnetProfile-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate GalEnetProfileInstance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+// might be needed to extend for parameter arguments, here just for setting the ConnectivityMode!!
+func (oo *omciCC) sendSetOnu2g(ctx context.Context, timeout int, highPrio bool) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send ONU2-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   0,
+		Attributes: me.AttributeValueMap{"CurrentConnectivityMode": connectivityModeValue},
+	}
+	meInstance, omciErr := me.NewOnu2G(meParams)
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode ONU2-G instance for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize ONU2-G set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send ONU2-G set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send ONU2-G-Set-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate ONU2-G", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateMBServiceProfile(ctx context.Context,
+	aPUniPort *onuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	instID := macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo)
+	logger.Debugw("send MBSP-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
+
+	meParams := me.ParamData{
+		EntityID: instID,
+		Attributes: me.AttributeValueMap{
+			"Priority":     0x8000,
+			"MaxAge":       20 * 256, //20s
+			"HelloTime":    2 * 256,  //2s
+			"ForwardDelay": 15 * 256, //15s
+			//note: DynamicFilteringAgeingTime is taken from omci lib default as
+			//  which is obviously different from default value used in python lib,
+			//  where the value seems to be 0 (ONU defined)  - to be considered in case of test artifacts ...
+		},
+	}
+
+	meInstance, omciErr := me.NewMacBridgeServiceProfile(meParams)
+	if omciErr.GetError() == nil {
+		//obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid), omci.AddDefaults(true))
+		if err != nil {
+			logger.Errorw("Cannot encode MBSP for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize MBSP create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send MBSP create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send MBSP-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate MBSP Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateMBPConfigData(ctx context.Context,
+	aPUniPort *onuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	instID := macBridgePortAniEID + aPUniPort.entityID
+	logger.Debugw("send MBPCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
+
+	meParams := me.ParamData{
+		EntityID: instID,
+		Attributes: me.AttributeValueMap{
+			"BridgeIdPointer": macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo),
+			"PortNum":         aPUniPort.macBpNo,
+			"TpType":          uint8(aPUniPort.portType),
+			"TpPointer":       aPUniPort.entityID,
+		},
+	}
+	meInstance, omciErr := me.NewMacBridgePortConfigurationData(meParams)
+	if omciErr.GetError() == nil {
+		//obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid), omci.AddDefaults(true))
+		if err != nil {
+			logger.Errorw("Cannot encode MBPCD for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize MBPCD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send MBPCD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send MBPCD-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateEVTOConfigData(ctx context.Context,
+	aPUniPort *onuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	instID := macBridgeServiceProfileEID + uint16(aPUniPort.macBpNo)
+	logger.Debugw("send EVTOCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
+
+	assType := uint8(2) // default AssociationType is PPTPEthUni
+	if aPUniPort.portType == uniVEIP {
+		assType = uint8(10) // for VEIP
+	}
+	meParams := me.ParamData{
+		EntityID: instID,
+		Attributes: me.AttributeValueMap{
+			"AssociationType":     assType,
+			"AssociatedMePointer": aPUniPort.entityID,
+		},
+	}
+	meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(meParams)
+	if omciErr.GetError() == nil {
+		//all setByCreate parameters already set, no default option required ...
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode EVTOCD for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize EVTOCD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibDownloadFsm.commChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send EVTOCD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send EVTOCD-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetOnuGLS(ctx context.Context, timeout int,
+	highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send ONU-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   0,
+		Attributes: requestedAttributes,
+	}
+	meInstance, omciErr := me.NewOnuG(meParams)
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode ONU-G instance for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize ONU-G set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send ONU-G set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send ONU-G-Set-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate ONU-G", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetUniGLS(ctx context.Context, aInstNo uint16, timeout int,
+	highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send UNI-G-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   aInstNo,
+		Attributes: requestedAttributes,
+	}
+	meInstance, omciErr := me.NewUniG(meParams)
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode UNI-G instance for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize UNI-G-Set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send UNIG-G-Set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send UNI-G-Set-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate UNI-G", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetVeipLS(ctx context.Context, aInstNo uint16, timeout int,
+	highPrio bool, requestedAttributes me.AttributeValueMap, rxChan chan Message) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send VEIP-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   aInstNo,
+		Attributes: requestedAttributes,
+	}
+	meInstance, omciErr := me.NewVirtualEthernetInterfacePoint(meParams)
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode VEIP instance for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize VEIP-Set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send VEIP-Set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send VEIP-Set-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate VEIP", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendGetMe(ctx context.Context, classID me.ClassID, entityID uint16, requestedAttributes me.AttributeValueMap,
+	timeout int, highPrio bool) *me.ManagedEntity {
+
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send get-request-msg", log.Fields{"classID": classID, "device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   entityID,
+		Attributes: requestedAttributes,
+	}
+	meInstance, omciErr := me.LoadManagedEntityDefinition(classID, meParams)
+	if omciErr.GetError() == nil {
+		meClassIDName := meInstance.GetName()
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.GetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorf("Cannot encode instance for get-request", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize get-request", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{(*oo.pOnuDeviceEntry).pMibUploadFsm.commChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send get-request-msg", log.Fields{"meClassIDName": meClassIDName, "Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debugw("send get-request-msg done", log.Fields{"meClassIDName": meClassIDName, "device-id": oo.deviceID})
+		return meInstance
+	}
+	logger.Errorw("Cannot generate meDefinition", log.Fields{"classID": classID, "Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateDot1PMapper(ctx context.Context, timeout int, highPrio bool,
+	aInstID uint16, rxChan chan Message) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send .1pMapper-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(aInstID), 16)})
+
+	meParams := me.ParamData{
+		EntityID:   aInstID,
+		Attributes: me.AttributeValueMap{},
+	}
+	meInstance, omciErr := me.NewIeee8021PMapperServiceProfile(meParams)
+	if omciErr.GetError() == nil {
+		//we have to set all 'untouched' parameters to default by some additional option parameter!!
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid), omci.AddDefaults(true))
+		if err != nil {
+			logger.Errorw("Cannot encode .1pMapper for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize .1pMapper create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send .1pMapper create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send .1pMapper-create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate .1pMapper", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateMBPConfigDataVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send MBPCD-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewMacBridgePortConfigurationData(params[0])
+	if omciErr.GetError() == nil {
+		//obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid), omci.AddDefaults(true))
+		if err != nil {
+			logger.Errorw("Cannot encode MBPCD for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize MBPCD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send MBPCD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send MBPCD-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateGemNCTPVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send GemNCTP-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewGemPortNetworkCtp(params[0])
+	if omciErr.GetError() == nil {
+		//obviously we have to set all 'untouched' parameters to default by some additional option parameter!!
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid), omci.AddDefaults(true))
+		if err != nil {
+			logger.Errorw("Cannot encode GemNCTP for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize GemNCTP create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send GemNCTP create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send GemNCTP-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate GemNCTP Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateGemIWTPVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send GemIwTp-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewGemInterworkingTerminationPoint(params[0])
+	if omciErr.GetError() == nil {
+		//all SetByCreate Parameters (assumed to be) set here, for optimisation no 'AddDefaults'
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode GemIwTp for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize GemIwTp create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send GemIwTp create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send GemIwTp-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate GemIwTp Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetTcontVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send TCont-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewTCont(params[0])
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode TCont for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize TCont set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send TCont set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send TCont-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate TCont Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetPrioQueueVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send PrioQueue-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewPriorityQueue(params[0])
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode PrioQueue for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize PrioQueue set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send PrioQueue set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send PrioQueue-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate PrioQueue Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetDot1PMapperVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send 1PMapper-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewIeee8021PMapperServiceProfile(params[0])
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode 1PMapper for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize 1PMapper set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send 1PMapper set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send 1PMapper-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate 1PMapper Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendCreateVtfdVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send VTFD-Create-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewVlanTaggingFilterData(params[0])
+	if omciErr.GetError() == nil {
+		//all SetByCreate Parameters (assumed to be) set here, for optimisation no 'AddDefaults'
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.CreateRequestType,
+			omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode VTFD for create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			//TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
+			//  return (dual format) error code that can be used at caller for immediate error treatment
+			//  (relevant to all used sendXX() methods and their error conditions)
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize VTFD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send VTFD create", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send VTFD-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate VTFD Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
+
+func (oo *omciCC) sendSetEvtocdVar(ctx context.Context, timeout int, highPrio bool,
+	rxChan chan Message, params ...me.ParamData) *me.ManagedEntity {
+	tid := oo.getNextTid(highPrio)
+	logger.Debugw("send EVTOCD-Set-msg:", log.Fields{"device-id": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16),
+		"InstId": strconv.FormatInt(int64(params[0].EntityID), 16)})
+
+	meInstance, omciErr := me.NewExtendedVlanTaggingOperationConfigurationData(params[0])
+	if omciErr.GetError() == nil {
+		omciLayer, msgLayer, err := omci.EncodeFrame(meInstance, omci.SetRequestType, omci.TransactionID(tid))
+		if err != nil {
+			logger.Errorw("Cannot encode EVTOCD for set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize EVTOCD set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{rxChan, oo.receiveOmciResponse},
+		}
+		err = oo.send(ctx, pkt, timeout, 0, highPrio, omciRxCallbackPair)
+		if err != nil {
+			logger.Errorw("Cannot send EVTOCD set", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send EVTOCD-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil
+}
diff --git a/internal/pkg/onuadaptercore/omci_test_request.go b/internal/pkg/onuadaptercore/omci_test_request.go
new file mode 100644
index 0000000..d7d967c
--- /dev/null
+++ b/internal/pkg/onuadaptercore/omci_test_request.go
@@ -0,0 +1,135 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+
+
+	gp "github.com/google/gopacket"
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+//omciTestRequest structure holds the information for the OMCI test
+type omciTestRequest struct {
+	deviceID     string
+	pDevOmciCC   *omciCC
+	started      bool
+	result       bool
+	exclusiveCc  bool
+	allowFailure bool
+	txSeqNo      uint16
+	verifyDone   chan<- bool
+}
+
+//newOmciTestRequest returns a new instance of OmciTestRequest
+func newOmciTestRequest(ctx context.Context,
+	deviceID string, omciCc *omciCC,
+	exclusive bool, allowFailure bool) *omciTestRequest {
+	logger.Debug("omciTestRequest-init")
+	var omciTestRequest omciTestRequest
+	omciTestRequest.deviceID = deviceID
+	omciTestRequest.pDevOmciCC = omciCc
+	omciTestRequest.started = false
+	omciTestRequest.result = false
+	omciTestRequest.exclusiveCc = exclusive
+	omciTestRequest.allowFailure = allowFailure
+
+	return &omciTestRequest
+}
+
+//
+func (oo *omciTestRequest) performOmciTest(ctx context.Context, execChannel chan<- bool) {
+	logger.Debug("omciTestRequest-start-test")
+
+	if oo.pDevOmciCC != nil {
+		oo.verifyDone = execChannel
+		// test functionality is limited to ONU-2G get request for the moment
+		// without yet checking the received response automatically here (might be improved ??)
+		tid := oo.pDevOmciCC.getNextTid(false)
+		onu2gBaseGet, _ := oo.createOnu2gBaseGet(tid)
+		omciRxCallbackPair := callbackPair{
+			cbKey:   tid,
+			cbEntry: callbackPairEntry{nil, oo.receiveOmciVerifyResponse},
+		}
+
+		logger.Debugw("performOmciTest-start sending frame", log.Fields{"for device-id": oo.deviceID})
+		// send with default timeout and normal prio
+		go oo.pDevOmciCC.send(ctx, onu2gBaseGet, ConstDefaultOmciTimeout, 0, false, omciRxCallbackPair)
+
+	} else {
+		logger.Errorw("performOmciTest: Device does not exist", log.Fields{"for device-id": oo.deviceID})
+	}
+}
+
+// these are OMCI related functions, could/should be collected in a separate file? TODO!!!
+// for a simple start just included in here
+//basic approach copied from bbsim, cmp /devices/onu.go and /internal/common/omci/mibpackets.go
+func (oo *omciTestRequest) createOnu2gBaseGet(tid uint16) ([]byte, error) {
+
+	request := &omci.GetRequest{
+		MeBasePacket: omci.MeBasePacket{
+			EntityClass:    me.Onu2GClassID,
+			EntityInstance: 0, //there is only the 0 instance of ONU2-G (still hard-coded - TODO!!!)
+		},
+		AttributeMask: 0xE000, //example hardcoded (TODO!!!) request EquId, OmccVersion, VendorCode
+	}
+
+	oo.txSeqNo = tid
+	pkt, err := serialize(omci.GetRequestType, request, tid)
+	if err != nil {
+		//omciLogger.WithFields(log.Fields{ ...
+		logger.Errorw("Cannot serialize Onu2-G GetRequest", log.Fields{"Err": err})
+		return nil, err
+	}
+	return pkt, nil
+}
+
+//supply a response handler - in this testobject the message is evaluated directly, no response channel used
+func (oo *omciTestRequest) receiveOmciVerifyResponse(omciMsg *omci.OMCI, packet *gp.Packet, respChan chan Message) error {
+
+	logger.Debugw("verify-omci-message-response received:", log.Fields{"omciMsgType": omciMsg.MessageType,
+		"transCorrId": omciMsg.TransactionID, "DeviceIdent": omciMsg.DeviceIdentifier})
+
+	if omciMsg.TransactionID == oo.txSeqNo {
+		logger.Debugw("verify-omci-message-response", log.Fields{"correct TransCorrId": omciMsg.TransactionID})
+	} else {
+		logger.Debugw("verify-omci-message-response error", log.Fields{"incorrect TransCorrId": omciMsg.TransactionID,
+			"expected": oo.txSeqNo})
+		oo.verifyDone <- false
+		return errors.New("unexpected TransCorrId")
+	}
+	if omciMsg.MessageType == omci.GetResponseType {
+		logger.Debugw("verify-omci-message-response", log.Fields{"correct RespType": omciMsg.MessageType})
+	} else {
+		logger.Debugw("verify-omci-message-response error", log.Fields{"incorrect RespType": omciMsg.MessageType,
+			"expected": omci.GetResponseType})
+		oo.verifyDone <- false
+		return errors.New("unexpected MessageType")
+	}
+
+
+	oo.result = true
+	oo.verifyDone <- true
+
+	return nil
+}
diff --git a/internal/pkg/onuadaptercore/omci_vlan_config.go b/internal/pkg/onuadaptercore/omci_vlan_config.go
new file mode 100644
index 0000000..15d16df
--- /dev/null
+++ b/internal/pkg/onuadaptercore/omci_vlan_config.go
@@ -0,0 +1,701 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"encoding/binary"
+	"errors"
+	"strconv"
+	"time"
+
+	"github.com/looplab/fsm"
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	of "github.com/opencord/voltha-protos/v3/go/openflow_13"
+)
+
+const (
+	cDefaultDownstreamMode = 0
+	cDefaultTpid           = 0x8100
+)
+
+const (
+	cFilterPrioOffset      = 28
+	cFilterVidOffset       = 15
+	cFilterTpidOffset      = 12
+	cFilterEtherTypeOffset = 0
+	cTreatTTROffset        = 30
+	cTreatPrioOffset       = 16
+	cTreatVidOffset        = 3
+	cTreatTpidOffset       = 0
+)
+const (
+	cFilterOuterOffset = 0
+	cFilterInnerOffset = 4
+	cTreatOuterOffset  = 8
+	cTreatInnerOffset  = 12
+)
+const (
+	cPrioIgnoreTag        uint32 = 15
+	cPrioDefaultFilter    uint32 = 14
+	cPrioDoNotFilter      uint32 = 8
+	cDoNotFilterVid       uint32 = 4096
+	cDoNotFilterTPID      uint32 = 0
+	cDoNotFilterEtherType uint32 = 0
+	cDoNotAddPrio         uint32 = 15
+	cCopyPrioFromInner    uint32 = 8
+	cDontCareVid          uint32 = 0
+	cDontCareTpid         uint32 = 0
+	cSetOutputTpidCopyDei uint32 = 4
+)
+
+const (
+	vlanEvStart          = "vlanEvStart"
+	vlanEvWaitTechProf   = "vlanEvWaitTechProf"
+	vlanEvContinueConfig = "vlanEvContinueConfig"
+	vlanEvStartConfig    = "vlanEvStartConfig"
+	vlanEvRxConfigVtfd   = "vlanEvRxConfigVtfd"
+	vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
+	vlanEvReset   = "vlanEvReset"
+	vlanEvRestart = "vlanEvRestart"
+)
+const (
+	vlanStDisabled        = "vlanStDisabled"
+	vlanStStarting        = "vlanStStarting"
+	vlanStWaitingTechProf = "vlanStWaitingTechProf"
+	vlanStConfigVtfd      = "vlanStConfigVtfd"
+	vlanStConfigEvtocd    = "vlanStConfigEvtocd"
+	vlanStConfigDone      = "vlanStConfigDone"
+	vlanStCleanEvtocd     = "vlanStCleanEvtocd"
+	vlanStCleanVtfd       = "vlanStCleanVtfd"
+	vlanStCleanupDone     = "vlanStCleanupDone"
+	vlanStResetting       = "vlanStResetting"
+)
+
+//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
+type UniVlanConfigFsm struct {
+	pDeviceHandler              *deviceHandler
+	pOmciCC                     *omciCC
+	pOnuUniPort                 *onuUniPort
+	pUniTechProf                *onuUniTechProf
+	pOnuDB                      *onuDeviceDB
+	techProfileID               uint16
+	requestEvent                OnuDeviceEvent
+	omciMIdsResponseReceived    chan bool //seperate channel needed for checking multiInstance OMCI message responses
+	pAdaptFsm                   *AdapterFsm
+	acceptIncrementalEvtoOption bool
+	matchVid     uint32
+	matchPcp     uint32
+	tagsToRemove uint32
+	setVid       uint32
+	setPcp       uint32
+	vtfdID       uint16
+	evtocdID     uint16
+}
+
+//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
+func NewUniVlanConfigFsm(apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort, apUniTechProf *onuUniTechProf,
+	apOnuDB *onuDeviceDB, aTechProfileID uint16, aRequestEvent OnuDeviceEvent, aName string,
+	aDeviceID string, aCommChannel chan Message,
+	aAcceptIncrementalEvto bool, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
+	instFsm := &UniVlanConfigFsm{
+		pDeviceHandler:              apDeviceHandler,
+		pOmciCC:                     apDevOmciCC,
+		pOnuUniPort:                 apUniPort,
+		pUniTechProf:                apUniTechProf,
+		pOnuDB:                      apOnuDB,
+		techProfileID:               aTechProfileID,
+		requestEvent:                aRequestEvent,
+		acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
+		matchVid:                    uint32(aMatchVlan),
+		setVid:                      uint32(aSetVlan),
+		setPcp:                      uint32(aSetPcp),
+	}
+	instFsm.tagsToRemove = 1            //one tag to remove as default setting
+	instFsm.matchPcp = cPrioDoNotFilter // do not Filter on prio as default
+	if instFsm.matchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
+		// no prio/vid filtering requested
+		instFsm.tagsToRemove = 0          //no tag pop action
+		instFsm.matchPcp = cPrioIgnoreTag // no vlan tag filtering
+		if instFsm.setPcp == cCopyPrioFromInner {
+			//in case of no filtering and configured PrioCopy ensure default prio setting to 0
+			// which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
+			// might collide with NoMatchVid/CopyPrio(/setVid) setting
+			// this was some precondition setting taken over from py adapter ..
+			instFsm.setPcp = 0
+		}
+	}
+
+	instFsm.pAdaptFsm = NewAdapterFsm(aName, aDeviceID, aCommChannel)
+	if instFsm.pAdaptFsm == nil {
+		logger.Errorw("UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
+			"device-id": aDeviceID})
+		return nil
+	}
+
+	instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
+		vlanStDisabled,
+		fsm.Events{
+			{Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
+			{Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
+			{Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
+			{Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
+			{Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
+			{Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd}, Dst: vlanStConfigDone},
+			//TODO:!!! Also define state transitions for cleanup states and timeouts
+			/*
+				{Name: vlanEvTimeoutSimple, Src: []string{
+					vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
+				{Name: vlanEvTimeoutMids, Src: []string{
+					vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
+			*/
+			// exceptional treatment for all states except vlanStResetting
+			{Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
+				vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone,
+				vlanStCleanEvtocd, vlanStCleanVtfd, vlanStCleanupDone},
+				Dst: vlanStResetting},
+			// the only way to get to resource-cleared disabled state again is via "resseting"
+			{Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
+		},
+
+		fsm.Callbacks{
+			"enter_state":                   func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
+			("enter_" + vlanStStarting):     func(e *fsm.Event) { instFsm.enterConfigStarting(e) },
+			("enter_" + vlanStConfigVtfd):   func(e *fsm.Event) { instFsm.enterConfigVtfd(e) },
+			("enter_" + vlanStConfigEvtocd): func(e *fsm.Event) { instFsm.enterConfigEvtocd(e) },
+			("enter_" + vlanStConfigDone):   func(e *fsm.Event) { instFsm.enterVlanConfigDone(e) },
+			("enter_" + vlanStCleanVtfd):    func(e *fsm.Event) { instFsm.enterCleanVtfd(e) },
+			("enter_" + vlanStCleanEvtocd):  func(e *fsm.Event) { instFsm.enterCleanEvtocd(e) },
+			("enter_" + vlanStCleanupDone):  func(e *fsm.Event) { instFsm.enterVlanCleanupDone(e) },
+			("enter_" + vlanStResetting):    func(e *fsm.Event) { instFsm.enterResetting(e) },
+			("enter_" + vlanStDisabled):     func(e *fsm.Event) { instFsm.enterDisabled(e) },
+		},
+	)
+	if instFsm.pAdaptFsm.pFsm == nil {
+		logger.Errorw("UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
+			"device-id": aDeviceID})
+		return nil
+	}
+
+	logger.Infow("UniVlanConfigFsm created", log.Fields{"device-id": aDeviceID,
+		"accIncrEvto": instFsm.acceptIncrementalEvtoOption,
+		"matchVid":    strconv.FormatInt(int64(instFsm.matchVid), 16),
+		"setVid":      strconv.FormatInt(int64(instFsm.setVid), 16),
+		"setPcp":      instFsm.setPcp})
+	return instFsm
+}
+
+func (oFsm *UniVlanConfigFsm) enterConfigStarting(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.pAdaptFsm.deviceID})
+
+	oFsm.omciMIdsResponseReceived = make(chan bool)
+	go oFsm.processOmciVlanMessages()
+	pConfigVlanStateAFsm := oFsm.pAdaptFsm
+	if pConfigVlanStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				//stick to pythonAdapter numbering scheme
+				oFsm.vtfdID = macBridgePortAniEID + oFsm.pOnuUniPort.entityID + oFsm.techProfileID
+				//cmp also usage in EVTOCDE create in omci_cc
+				oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
+
+				if oFsm.pUniTechProf.getTechProfileDone(oFsm.pOnuUniPort.uniID, oFsm.techProfileID) {
+					// let the vlan processing begin
+					_ = a_pAFsm.pFsm.Event(vlanEvStartConfig)
+				} else {
+					// set to waiting for Techprofile
+					_ = a_pAFsm.pFsm.Event(vlanEvWaitTechProf)
+				}
+			}
+		}(pConfigVlanStateAFsm)
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) enterConfigVtfd(e *fsm.Event) {
+	if oFsm.setVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
+		// meaning transparent setup - no specific VTFD setting required
+		logger.Debugw("UniVlanConfigFsm: no VTFD config required", log.Fields{
+			"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+		// let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		pConfigVlanStateAFsm := oFsm.pAdaptFsm
+		go func(a_pAFsm *AdapterFsm) {
+			_ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
+		}(pConfigVlanStateAFsm)
+	} else {
+		logger.Debugw("UniVlanConfigFsm create VTFD", log.Fields{
+			"EntitytId": strconv.FormatInt(int64(oFsm.vtfdID), 16),
+			"in state":  e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+		vlanFilterList := make([]uint16, 12)
+		vlanFilterList[0] = uint16(oFsm.setVid) // setVid is assumed to be masked already by the caller to 12 bit
+		meParams := me.ParamData{
+			EntityID: oFsm.vtfdID,
+			Attributes: me.AttributeValueMap{
+				"VlanFilterList":   vlanFilterList,
+				"ForwardOperation": uint8(0x10), //VID investigation
+				"NumberOfEntries":  uint8(1),
+			},
+		}
+		meInstance := oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
+			oFsm.pAdaptFsm.commChan, meParams)
+		//accept also nil as (error) return value for writing to LastTx
+		//  - this avoids misinterpretation of new received OMCI messages
+		//TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
+		//  send shall return (dual format) error code that can be used here for immediate error treatment
+		//  (relevant to all used sendXX() methods in this (and other) FSM's)
+		oFsm.pOmciCC.pLastTxMeInstance = meInstance
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	go oFsm.performConfigEvtocdEntries()
+}
+
+func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	if oFsm.pDeviceHandler != nil {
+		oFsm.pDeviceHandler.deviceProcStatusUpdate(oFsm.requestEvent)
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) enterCleanVtfd(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm Tx Delete::VTFD", log.Fields{
+		/*"EntitytId": strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),*/
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+}
+
+func (oFsm *UniVlanConfigFsm) enterCleanEvtocd(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm  cleanup EVTOCD", log.Fields{
+		/*"EntitytId": strconv.FormatInt(int64(oFsm.macBPCD0ID), 16),
+		"TPPtr":     strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),*/
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+}
+
+func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm - VLAN cleanup done", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+
+	pConfigVlanStateAFsm := oFsm.pAdaptFsm
+	if pConfigVlanStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(vlanEvReset)
+			}
+		}(pConfigVlanStateAFsm)
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) enterResetting(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+
+	pConfigVlanStateAFsm := oFsm.pAdaptFsm
+	if pConfigVlanStateAFsm != nil {
+		// abort running message processing
+		fsmAbortMsg := Message{
+			Type: TestMsg,
+			Data: TestMessage{
+				TestMessageVal: AbortMessageProcessing,
+			},
+		}
+		pConfigVlanStateAFsm.commChan <- fsmAbortMsg
+
+		//try to restart the FSM to 'disabled', decouple event transfer
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(vlanEvRestart)
+			}
+		}(pConfigVlanStateAFsm)
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) enterDisabled(e *fsm.Event) {
+	logger.Debugw("UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	if oFsm.pDeviceHandler != nil {
+		//request removal of 'reference' in the Handler (completely clear the FSM)
+		go oFsm.pDeviceHandler.RemoveVlanFilterFsm(oFsm.pOnuUniPort)
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) processOmciVlanMessages() { //ctx context.Context?
+	logger.Debugw("Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+loop:
+	for {
+		// case <-ctx.Done():
+		// 	logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.pAdaptFsm.deviceID})
+		// 	break loop
+		message, ok := <-oFsm.pAdaptFsm.commChan
+		if !ok {
+			logger.Info("UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+			// but then we have to ensure a restart of the FSM as well - as exceptional procedure
+			_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
+			break loop
+		}
+		logger.Debugw("UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+
+		switch message.Type {
+		case TestMsg:
+			msg, _ := message.Data.(TestMessage)
+			if msg.TestMessageVal == AbortMessageProcessing {
+				logger.Infow("UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+				break loop
+			}
+			logger.Warnw("UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "MessageVal": msg.TestMessageVal})
+		case OMCI:
+			msg, _ := message.Data.(OmciMessage)
+			oFsm.handleOmciVlanConfigMessage(msg)
+		default:
+			logger.Warn("UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
+				"message.Type": message.Type})
+		}
+	}
+	logger.Infow("End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+}
+
+func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(msg OmciMessage) {
+	logger.Debugw("Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
+		"msgType": msg.OmciMsg.MessageType})
+
+	switch msg.OmciMsg.MessageType {
+	case omci.CreateResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCreateResponse)
+			if msgLayer == nil {
+				logger.Error("Omci Msg layer could not be detected for CreateResponse")
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.CreateResponse)
+			if !msgOk {
+				logger.Error("Omci Msg layer could not be assigned for CreateResponse")
+				return
+			}
+			logger.Debugw("CreateResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw("Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+				// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+				return
+			}
+			if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
+				msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
+				// maybe we can use just the same eventName for different state transitions like "forward"
+				//   - might be checked, but so far I go for sure and have to inspect the concrete state events ...
+				switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
+				case "VlanTaggingFilterData":
+					{ // let the FSM proceed ...
+						_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
+					}
+				}
+			}
+		} //CreateResponseType
+	case omci.SetResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
+			if msgLayer == nil {
+				logger.Error("UniVlanConfigFsm - Omci Msg layer could not be detected for SetResponse")
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.SetResponse)
+			if !msgOk {
+				logger.Error("UniVlanConfigFsm - Omci Msg layer could not be assigned for SetResponse")
+				return
+			}
+			logger.Debugw("UniVlanConfigFsm SetResponse Data", log.Fields{"deviceId": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw("UniVlanConfigFsm - Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+				// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+				return
+			}
+			if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
+				msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
+				switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
+				case "ExtendedVlanTaggingOperationConfigurationData":
+					{ // let the EVTO config proceed by stopping the wait function
+						oFsm.omciMIdsResponseReceived <- true
+					}
+				}
+			}
+		} //SetResponseType
+	default:
+		{
+			logger.Errorw("UniVlanConfigFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
+			return
+		}
+	}
+}
+
+func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries() {
+	{ // for local var
+		// EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
+		// we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
+		logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD", log.Fields{
+			"EntitytId":  strconv.FormatInt(int64(oFsm.evtocdID), 16),
+			"i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
+			"device-id":  oFsm.pAdaptFsm.deviceID})
+		meParams := me.ParamData{
+			EntityID: oFsm.evtocdID,
+			Attributes: me.AttributeValueMap{
+				"InputTpid":      uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
+				"OutputTpid":     uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
+				"DownstreamMode": uint8(cDefaultDownstreamMode),
+			},
+		}
+		meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
+			oFsm.pAdaptFsm.commChan, meParams)
+		//accept also nil as (error) return value for writing to LastTx
+		//  - this avoids misinterpretation of new received OMCI messages
+		oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+		//verify response
+		err := oFsm.waitforOmciResponse()
+		if err != nil {
+			logger.Errorw("Evtocd set TPID failed, aborting VlanConfig FSM!",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+			_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
+			return
+		}
+	} //for local var
+
+	if oFsm.setVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
+		//transparent transmission required
+		logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
+			"device-id": oFsm.pAdaptFsm.deviceID})
+		sliceEvtocdRule := make([]uint8, 16)
+		// fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
+		binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
+			cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
+				cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
+				cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
+
+		binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
+			cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
+				cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
+				cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
+				cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
+
+		binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
+			0<<cTreatTTROffset| // Do not pop any tags
+				cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
+				cDontCareVid<<cTreatVidOffset| // Outer VID don't care
+				cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
+
+		binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
+			cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
+				cDontCareVid<<cTreatVidOffset| // Outer VID don't care
+				cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
+
+		meParams := me.ParamData{
+			EntityID: oFsm.evtocdID,
+			Attributes: me.AttributeValueMap{
+				"ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
+			},
+		}
+		meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
+			oFsm.pAdaptFsm.commChan, meParams)
+		//accept also nil as (error) return value for writing to LastTx
+		//  - this avoids misinterpretation of new received OMCI messages
+		oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+		//verify response
+		err := oFsm.waitforOmciResponse()
+		if err != nil {
+			logger.Errorw("Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+			_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
+			return
+		}
+	} else {
+		// according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
+		if oFsm.acceptIncrementalEvtoOption {
+			// this defines VID translation scenario: singletagged->singletagged (if not transparent)
+			logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
+				"device-id": oFsm.pAdaptFsm.deviceID})
+			sliceEvtocdRule := make([]uint8, 16)
+			// fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
+			binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
+				cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
+					cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
+					cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
+
+			binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
+				oFsm.matchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
+					oFsm.matchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
+					cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
+					cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
+
+			binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
+				oFsm.tagsToRemove<<cTreatTTROffset| // either 1 or 0
+					cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
+					cDontCareVid<<cTreatVidOffset| // Outer VID don't care
+					cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
+
+			binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
+				oFsm.setPcp<<cTreatPrioOffset| // as configured in flow
+					oFsm.setVid<<cTreatVidOffset| //as configured in flow
+					cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
+
+			meParams := me.ParamData{
+				EntityID: oFsm.evtocdID,
+				Attributes: me.AttributeValueMap{
+					"ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
+				},
+			}
+			meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
+				oFsm.pAdaptFsm.commChan, meParams)
+			//accept also nil as (error) return value for writing to LastTx
+			//  - this avoids misinterpretation of new received OMCI messages
+			oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+			//verify response
+			err := oFsm.waitforOmciResponse()
+			if err != nil {
+				logger.Errorw("Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
+					log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+				_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
+				return
+			}
+		} else {
+			//not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
+			{ // just for local var's
+				// this defines stacking scenario: untagged->singletagged
+				logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
+					"device-id": oFsm.pAdaptFsm.deviceID})
+				sliceEvtocdRule := make([]uint8, 16)
+				// fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
+					cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
+						cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
+						cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
+
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
+					cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
+						cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
+						cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
+						cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
+
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
+					0<<cTreatTTROffset| // Do not pop any tags
+						cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
+						cDontCareVid<<cTreatVidOffset| // Outer VID don't care
+						cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
+
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
+					0<<cTreatPrioOffset| // vlan prio set to 0
+						//   (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
+						oFsm.setVid<<cTreatVidOffset| // Outer VID don't care
+						cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
+
+				meParams := me.ParamData{
+					EntityID: oFsm.evtocdID,
+					Attributes: me.AttributeValueMap{
+						"ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
+					},
+				}
+				meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
+					oFsm.pAdaptFsm.commChan, meParams)
+				//accept also nil as (error) return value for writing to LastTx
+				//  - this avoids misinterpretation of new received OMCI messages
+				oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+				//verify response
+				err := oFsm.waitforOmciResponse()
+				if err != nil {
+					logger.Errorw("Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
+						log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+					_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
+					return
+				}
+			} //just for local var's
+			{ // just for local var's
+				// this defines 'stacking' scenario: priotagged->singletagged
+				logger.Debugw("UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
+					"device-id": oFsm.pAdaptFsm.deviceID})
+				sliceEvtocdRule := make([]uint8, 16)
+				// fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
+					cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
+						cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
+						cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
+
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
+					cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
+						0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
+						cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
+						cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
+
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
+					1<<cTreatTTROffset| // pop the prio-tag
+						cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
+						cDontCareVid<<cTreatVidOffset| // Outer VID don't care
+						cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
+
+				binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
+					cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
+						//   (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
+						oFsm.setVid<<cTreatVidOffset| // Outer VID as configured
+						cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
+
+				meParams := me.ParamData{
+					EntityID: oFsm.evtocdID,
+					Attributes: me.AttributeValueMap{
+						"ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
+					},
+				}
+				meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
+					oFsm.pAdaptFsm.commChan, meParams)
+				//accept also nil as (error) return value for writing to LastTx
+				//  - this avoids misinterpretation of new received OMCI messages
+				oFsm.pOmciCC.pLastTxMeInstance = meInstance
+
+				//verify response
+				err := oFsm.waitforOmciResponse()
+				if err != nil {
+					logger.Errorw("Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
+						log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+					_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
+					return
+				}
+			} //just for local var's
+		}
+	}
+
+	logger.Debugw("EVTOCD set loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	_ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
+}
+
+func (oFsm *UniVlanConfigFsm) waitforOmciResponse() error {
+	select {
+	case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
+		logger.Warnw("UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+		return errors.New("uniVlanConfigFsm multi entity timeout")
+	case success := <-oFsm.omciMIdsResponseReceived:
+		if success {
+			logger.Debug("UniVlanConfigFsm multi entity response received")
+			return nil
+		}
+		// should not happen so far
+		logger.Warnw("UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+		return errors.New("uniVlanConfigFsm multi entity responseError")
+	}
+}
diff --git a/internal/pkg/onuadaptercore/onu_device_db.go b/internal/pkg/onuadaptercore/onu_device_db.go
new file mode 100644
index 0000000..ca954d6
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_device_db.go
@@ -0,0 +1,131 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"fmt"
+	"reflect"
+	"sort"
+
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+type meDbMap map[me.ClassID]map[uint16]me.AttributeValueMap
+
+//onuDeviceDB structure holds information about known ME's
+type onuDeviceDB struct {
+	ctx             context.Context
+	pOnuDeviceEntry *OnuDeviceEntry
+	meDb            meDbMap
+}
+
+//newOnuDeviceDB returns a new instance for a specific ONU_Device_Entry
+func newOnuDeviceDB(ctx context.Context, aPOnuDeviceEntry *OnuDeviceEntry) *onuDeviceDB {
+	logger.Debugw("Init OnuDeviceDB for:", log.Fields{"device-id": aPOnuDeviceEntry.deviceID})
+	var onuDeviceDB onuDeviceDB
+	onuDeviceDB.ctx = ctx
+	onuDeviceDB.pOnuDeviceEntry = aPOnuDeviceEntry
+	onuDeviceDB.meDb = make(meDbMap)
+
+	return &onuDeviceDB
+}
+
+func (onuDeviceDB *onuDeviceDB) PutMe(meClassID me.ClassID, meEntityID uint16, meAttributes me.AttributeValueMap) {
+
+	if me.OnuDataClassID == meClassID {
+		return
+	}
+
+	meInstMap, ok := onuDeviceDB.meDb[meClassID]
+	if !ok {
+		logger.Debugw("meClassID not found - add to db :", log.Fields{"device-id": onuDeviceDB.pOnuDeviceEntry.deviceID})
+		meInstMap = make(map[uint16]me.AttributeValueMap)
+		onuDeviceDB.meDb[meClassID] = meInstMap
+		onuDeviceDB.meDb[meClassID][meEntityID] = meAttributes
+	} else {
+		meAttribs, ok := meInstMap[meEntityID]
+		if !ok {
+			/* verbose logging, avoid in >= debug level
+			logger.Debugw("meEntityId not found - add to db :", log.Fields{"device-id": onuDeviceDB.pOnuDeviceEntry.deviceID})
+			*/
+			meInstMap[meEntityID] = meAttributes
+		} else {
+			/* verbose logging, avoid in >= debug level
+			logger.Debugw("ME-Instance exists already: merge attribute data :", log.Fields{"device-id": onuDeviceDB.pOnuDeviceEntry.deviceID, "meAttribs": meAttribs})
+			*/
+			for k, v := range meAttributes {
+				meAttribs[k] = v
+			}
+			meInstMap[meEntityID] = meAttribs
+			/* verbose logging, avoid in >= debug level
+			logger.Debugw("ME-Instance updated :", log.Fields{"device-id": onuDeviceDB.pOnuDeviceEntry.deviceID, "meAttribs": meAttribs})
+			*/
+		}
+	}
+}
+
+func (onuDeviceDB *onuDeviceDB) GetMe(meClassID me.ClassID, meEntityID uint16) me.AttributeValueMap {
+
+	if meAttributes, present := onuDeviceDB.meDb[meClassID][meEntityID]; present {
+		/* verbose logging, avoid in >= debug level
+		logger.Debugw("ME found:", log.Fields{"meClassID": meClassID, "meEntityID": meEntityID, "meAttributes": meAttributes,
+			"device-id": onuDeviceDB.pOnuDeviceEntry.deviceID})
+		*/
+		return meAttributes
+	}
+	return nil
+}
+
+func (onuDeviceDB *onuDeviceDB) getUint32Attrib(meAttribute interface{}) (uint32, error) {
+
+	switch reflect.TypeOf(meAttribute).Kind() {
+	case reflect.Float64:
+		//JSON numbers by default are unmarshaled into values of float64 type if type information is not present
+		return uint32(meAttribute.(float64)), nil
+	case reflect.Uint32:
+		return uint32(meAttribute.(uint32)), nil
+	default:
+		return uint32(0), fmt.Errorf(fmt.Sprintf("wrong interface-type received-%s", onuDeviceDB.pOnuDeviceEntry.deviceID))
+	}
+}
+
+func (onuDeviceDB *onuDeviceDB) getSortedInstKeys(meClassID me.ClassID) []uint16 {
+
+	var meInstKeys []uint16
+
+	meInstMap := onuDeviceDB.meDb[meClassID]
+
+	for k := range meInstMap {
+		meInstKeys = append(meInstKeys, k)
+	}
+	logger.Debugw("meInstKeys - input order :", log.Fields{"meInstKeys": meInstKeys}) //TODO: delete the line after test phase!
+	sort.Slice(meInstKeys, func(i, j int) bool { return meInstKeys[i] < meInstKeys[j] })
+	logger.Debugw("meInstKeys - output order :", log.Fields{"meInstKeys": meInstKeys}) //TODO: delete the line after test phase!
+	return meInstKeys
+}
+
+func (onuDeviceDB *onuDeviceDB) logMeDb() {
+	logger.Debugw("ME instances stored for :", log.Fields{"device-id": onuDeviceDB.pOnuDeviceEntry.deviceID})
+	for meClassID, meInstMap := range onuDeviceDB.meDb {
+		for meEntityID, meAttribs := range meInstMap {
+			logger.Debugw("ME instance: ", log.Fields{"meClassID": meClassID, "meEntityID": meEntityID, "meAttribs": meAttribs, "device-id": onuDeviceDB.pOnuDeviceEntry.deviceID})
+		}
+	}
+}
diff --git a/internal/pkg/onuadaptercore/onu_device_entry.go b/internal/pkg/onuadaptercore/onu_device_entry.go
new file mode 100644
index 0000000..5d888b1
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_device_entry.go
@@ -0,0 +1,436 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+	"time"
+
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+
+
+	"github.com/looplab/fsm"
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+const (
+	ulEvStart              = "ulEvStart"
+	ulEvResetMib           = "ulEvResetMib"
+	ulEvGetVendorAndSerial = "ulEvGetVendorAndSerial"
+	ulEvGetEquipmentID     = "ulEvGetEquipmentId"
+	ulEvGetFirstSwVersion  = "ulEvGetFirstSwVersion"
+	ulEvGetSecondSwVersion = "ulEvGetSecondSwVersion"
+	ulEvGetMacAddress      = "ulEvGetMacAddress"
+	ulEvGetMibTemplate     = "ulEvGetMibTemplate"
+	ulEvUploadMib          = "ulEvUploadMib"
+	ulEvExamineMds         = "ulEvExamineMds"
+	ulEvSuccess            = "ulEvSuccess"
+	ulEvMismatch           = "ulEvMismatch"
+	ulEvAuditMib           = "ulEvAuditMib"
+	ulEvForceResync        = "ulEvForceResync"
+	ulEvDiffsFound         = "ulEvDiffsFound"
+	ulEvTimeout            = "ulEvTimeout"
+	ulEvStop               = "ulEvStop"
+)
+const (
+	ulStDisabled               = "ulStDisabled"
+	ulStStarting               = "ulStStarting"
+	ulStResettingMib           = "ulStResettingMib"
+	ulStGettingVendorAndSerial = "ulStGettingVendorAndSerial"
+	ulStGettingEquipmentID     = "ulStGettingEquipmentID"
+	ulStGettingFirstSwVersion  = "ulStGettingFirstSwVersion"
+	ulStGettingSecondSwVersion = "ulStGettingSecondSwVersion"
+	ulStGettingMacAddress      = "ulStGettingMacAddress"
+	ulStGettingMibTemplate     = "ulStGettingMibTemplate"
+	ulStUploading              = "ulStUploading"
+	ulStInSync                 = "ulStInSync"
+	ulStExaminingMds           = "ulStExaminingMds"
+	ulStResynchronizing        = "ulStResynchronizing"
+	ulStAuditing               = "ulStAuditing"
+	ulStOutOfSync              = "ulStOutOfSync"
+)
+
+const (
+	dlEvStart         = "dlEvStart"
+	dlEvCreateGal     = "dlEvCreateGal"
+	dlEvRxGalResp     = "dlEvRxGalResp"
+	dlEvRxOnu2gResp   = "dlEvRxOnu2gResp"
+	dlEvRxBridgeResp  = "dlEvRxBridgeResp"
+	dlEvTimeoutSimple = "dlEvTimeoutSimple"
+	dlEvTimeoutBridge = "dlEvTimeoutBridge"
+	dlEvReset         = "dlEvReset"
+	dlEvRestart       = "dlEvRestart"
+)
+const (
+	dlStDisabled     = "dlStDisabled"
+	dlStStarting     = "dlStStarting"
+	dlStCreatingGal  = "dlStCreatingGal"
+	dlStSettingOnu2g = "dlStSettingOnu2g"
+	dlStBridgeInit   = "dlStBridgeInit"
+	dlStDownloaded   = "dlStDownloaded"
+	dlStResetting    = "dlStResetting"
+)
+
+const (
+	cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
+	cSuffixMibTemplateKvStore   = "%s/%s/%s"
+)
+
+// OnuDeviceEvent - event of interest to Device Adapters and OpenOMCI State Machines
+type OnuDeviceEvent int
+
+const (
+
+	DeviceStatusInit OnuDeviceEvent = 0
+	MibDatabaseSync OnuDeviceEvent = 1
+	OmciCapabilitiesDone OnuDeviceEvent = 2
+	MibDownloadDone OnuDeviceEvent = 3
+	UniLockStateDone OnuDeviceEvent = 4
+	UniUnlockStateDone OnuDeviceEvent = 5
+	UniAdminStateDone OnuDeviceEvent = 6
+	PortLinkUp OnuDeviceEvent = 7
+	PortLinkDw OnuDeviceEvent = 8
+	OmciAniConfigDone OnuDeviceEvent = 9
+	OmciVlanFilterDone OnuDeviceEvent = 10
+)
+
+type activityDescr struct {
+	databaseClass func() error
+	auditDelay uint16
+}
+
+// OmciDeviceFsms - FSM event mapping to database class and time to wait between audits
+type OmciDeviceFsms map[string]activityDescr
+
+// AdapterFsm - Adapter FSM details including channel, event and  device
+type AdapterFsm struct {
+	fsmName  string
+	deviceID string
+	commChan chan Message
+	pFsm     *fsm.FSM
+}
+
+//NewAdapterFsm - FSM details including event, device and channel.
+func NewAdapterFsm(aName string, aDeviceID string, aCommChannel chan Message) *AdapterFsm {
+	aFsm := &AdapterFsm{
+		fsmName:  aName,
+		deviceID: aDeviceID,
+		commChan: aCommChannel,
+	}
+	return aFsm
+}
+
+//Start starts (logs) the omci agent
+func (oo *AdapterFsm) logFsmStateChange(e *fsm.Event) {
+	logger.Debugw("FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
+		"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst)})
+}
+
+//OntDeviceEntry structure holds information about the attached FSM'as and their communication
+
+const (
+	firstSwImageMeID  = 0
+	secondSwImageMeID = 1
+)
+const onugMeID = 0
+const onu2gMeID = 0
+const ipHostConfigDataMeID = 1
+const onugSerialNumberLen = 8
+const omciMacAddressLen = 6
+
+type swImages struct {
+	version  string
+	isActive uint8
+}
+
+// OnuDeviceEntry - ONU device info and FSM events.
+type OnuDeviceEntry struct {
+	deviceID           string
+	baseDeviceHandler  *deviceHandler
+	coreProxy          adapterif.CoreProxy
+	adapterProxy       adapterif.AdapterProxy
+	started            bool
+	PDevOmciCC         *omciCC
+	pOnuDB             *onuDeviceDB
+	mibTemplateKVStore *db.Backend
+	vendorID           string
+	serialNumber       string
+	equipmentID        string
+	swImages           [secondSwImageMeID + 1]swImages
+	activeSwVersion    string
+	macAddress         string
+	mibDbClass    func() error
+	supportedFsms OmciDeviceFsms
+	devState      OnuDeviceEvent
+	mibAuditDelay uint16
+	mibDebugLevel string
+
+	pMibUploadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
+	pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
+	omciMessageReceived              chan bool    //seperate channel needed by DownloadFsm
+	omciRebootMessageReceivedChannel chan Message // channel needed by Reboot request
+}
+
+//newOnuDeviceEntry returns a new instance of a OnuDeviceEntry
+//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
+func newOnuDeviceEntry(ctx context.Context, deviceID string, kVStoreHost string, kVStorePort int, kvStoreType string, deviceHandler *deviceHandler,
+	coreProxy adapterif.CoreProxy, adapterProxy adapterif.AdapterProxy,
+	supportedFsmsPtr *OmciDeviceFsms) *OnuDeviceEntry {
+	logger.Infow("init-onuDeviceEntry", log.Fields{"device-id": deviceID})
+	var onuDeviceEntry OnuDeviceEntry
+	onuDeviceEntry.started = false
+	onuDeviceEntry.deviceID = deviceID
+	onuDeviceEntry.baseDeviceHandler = deviceHandler
+	onuDeviceEntry.coreProxy = coreProxy
+	onuDeviceEntry.adapterProxy = adapterProxy
+	onuDeviceEntry.devState = DeviceStatusInit
+	onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan Message, 2048)
+	if supportedFsmsPtr != nil {
+		onuDeviceEntry.supportedFsms = *supportedFsmsPtr
+	} else {
+		//var mibSyncFsm = NewMibSynchronizer()
+		// use some internaö defaults, if not defined from outside
+		onuDeviceEntry.supportedFsms = OmciDeviceFsms{
+			"mib-synchronizer": {
+				//mibSyncFsm,        // Implements the MIB synchronization state machine
+				onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
+				//true,                             // Advertise events on OpenOMCI event bus
+				60, // Time to wait between MIB audits.  0 to disable audits.
+				// map[string]func() error{
+				// 	"mib-upload":    onuDeviceEntry.MibUploadTask,
+				// 	"mib-template":  onuDeviceEntry.MibTemplateTask,
+				// 	"get-mds":       onuDeviceEntry.GetMdsTask,
+				// 	"mib-audit":     onuDeviceEntry.GetMdsTask,
+				// 	"mib-resync":    onuDeviceEntry.MibResyncTask,
+				// 	"mib-reconcile": onuDeviceEntry.MibReconcileTask,
+				// },
+			},
+		}
+	}
+	onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
+	logger.Debug("access2mibDbClass")
+	go onuDeviceEntry.mibDbClass()
+	onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
+	logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
+
+	onuDeviceEntry.mibDebugLevel = "normal" //set to "verbose" if you want to have all output, possibly later also per config option!
+	mibUploadChan := make(chan Message, 2048)
+	onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", deviceID, mibUploadChan)
+	onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
+		ulStDisabled,
+		fsm.Events{
+
+			{Name: ulEvStart, Src: []string{ulStDisabled}, Dst: ulStStarting},
+
+			{Name: ulEvResetMib, Src: []string{ulStStarting}, Dst: ulStResettingMib},
+			{Name: ulEvGetVendorAndSerial, Src: []string{ulStResettingMib}, Dst: ulStGettingVendorAndSerial},
+			{Name: ulEvGetEquipmentID, Src: []string{ulStGettingVendorAndSerial}, Dst: ulStGettingEquipmentID},
+			{Name: ulEvGetFirstSwVersion, Src: []string{ulStGettingEquipmentID}, Dst: ulStGettingFirstSwVersion},
+			{Name: ulEvGetSecondSwVersion, Src: []string{ulStGettingFirstSwVersion}, Dst: ulStGettingSecondSwVersion},
+			{Name: ulEvGetMacAddress, Src: []string{ulStGettingSecondSwVersion}, Dst: ulStGettingMacAddress},
+			{Name: ulEvGetMibTemplate, Src: []string{ulStGettingMacAddress}, Dst: ulStGettingMibTemplate},
+
+			{Name: ulEvUploadMib, Src: []string{ulStGettingMibTemplate}, Dst: ulStUploading},
+			{Name: ulEvExamineMds, Src: []string{ulStStarting}, Dst: ulStExaminingMds},
+
+			{Name: ulEvSuccess, Src: []string{ulStGettingMibTemplate}, Dst: ulStInSync},
+			{Name: ulEvSuccess, Src: []string{ulStUploading}, Dst: ulStInSync},
+
+			{Name: ulEvSuccess, Src: []string{ulStExaminingMds}, Dst: ulStInSync},
+			{Name: ulEvMismatch, Src: []string{ulStExaminingMds}, Dst: ulStResynchronizing},
+
+			{Name: ulEvAuditMib, Src: []string{ulStInSync}, Dst: ulStAuditing},
+
+			{Name: ulEvSuccess, Src: []string{ulStOutOfSync}, Dst: ulStInSync},
+			{Name: ulEvAuditMib, Src: []string{ulStOutOfSync}, Dst: ulStAuditing},
+
+			{Name: ulEvSuccess, Src: []string{ulStAuditing}, Dst: ulStInSync},
+			{Name: ulEvMismatch, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
+			{Name: ulEvForceResync, Src: []string{ulStAuditing}, Dst: ulStResynchronizing},
+
+			{Name: ulEvSuccess, Src: []string{ulStResynchronizing}, Dst: ulStInSync},
+			{Name: ulEvDiffsFound, Src: []string{ulStResynchronizing}, Dst: ulStOutOfSync},
+
+			{Name: ulEvTimeout, Src: []string{ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
+				ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
+				ulStInSync, ulStOutOfSync, ulStAuditing}, Dst: ulStStarting},
+
+			{Name: ulEvStop, Src: []string{ulStStarting, ulStResettingMib, ulStGettingVendorAndSerial, ulStGettingEquipmentID, ulStGettingFirstSwVersion,
+				ulStGettingSecondSwVersion, ulStGettingMacAddress, ulStGettingMibTemplate, ulStUploading, ulStResynchronizing, ulStExaminingMds,
+				ulStInSync, ulStOutOfSync, ulStAuditing}, Dst: ulStDisabled},
+		},
+
+		fsm.Callbacks{
+			"enter_state":                           func(e *fsm.Event) { onuDeviceEntry.pMibUploadFsm.logFsmStateChange(e) },
+			("enter_" + ulStStarting):               func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
+			("enter_" + ulStResettingMib):           func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(e) },
+			("enter_" + ulStGettingVendorAndSerial): func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(e) },
+			("enter_" + ulStGettingEquipmentID):     func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(e) },
+			("enter_" + ulStGettingFirstSwVersion):  func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(e) },
+			("enter_" + ulStGettingSecondSwVersion): func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(e) },
+			("enter_" + ulStGettingMacAddress):      func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(e) },
+			("enter_" + ulStGettingMibTemplate):     func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplate(e) },
+			("enter_" + ulStUploading):              func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
+			("enter_" + ulStExaminingMds):           func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
+			("enter_" + ulStResynchronizing):        func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
+			("enter_" + ulStAuditing):               func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
+			("enter_" + ulStOutOfSync):              func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
+			("enter_" + ulStInSync):                 func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
+		},
+	)
+	mibDownloadChan := make(chan Message, 2048)
+	onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", deviceID, mibDownloadChan)
+	onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
+		dlStDisabled,
+		fsm.Events{
+
+			{Name: dlEvStart, Src: []string{dlStDisabled}, Dst: dlStStarting},
+
+			{Name: dlEvCreateGal, Src: []string{dlStStarting}, Dst: dlStCreatingGal},
+			{Name: dlEvRxGalResp, Src: []string{dlStCreatingGal}, Dst: dlStSettingOnu2g},
+			{Name: dlEvRxOnu2gResp, Src: []string{dlStSettingOnu2g}, Dst: dlStBridgeInit},
+			// the bridge state is used for multi ME config for alle UNI related ports
+			// maybe such could be reflected in the state machine as well (port number parametrized)
+			// but that looks not straightforward here - so we keep it simple here for the beginning(?)
+			{Name: dlEvRxBridgeResp, Src: []string{dlStBridgeInit}, Dst: dlStDownloaded},
+
+			{Name: dlEvTimeoutSimple, Src: []string{dlStCreatingGal, dlStSettingOnu2g}, Dst: dlStStarting},
+			{Name: dlEvTimeoutBridge, Src: []string{dlStBridgeInit}, Dst: dlStStarting},
+
+			{Name: dlEvReset, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
+				dlStBridgeInit, dlStDownloaded}, Dst: dlStResetting},
+			// exceptional treatment for all states except dlStResetting
+			{Name: dlEvRestart, Src: []string{dlStStarting, dlStCreatingGal, dlStSettingOnu2g,
+				dlStBridgeInit, dlStDownloaded, dlStResetting}, Dst: dlStDisabled},
+		},
+
+		fsm.Callbacks{
+			"enter_state":                 func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(e) },
+			("enter_" + dlStStarting):     func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(e) },
+			("enter_" + dlStCreatingGal):  func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(e) },
+			("enter_" + dlStSettingOnu2g): func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(e) },
+			("enter_" + dlStBridgeInit):   func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(e) },
+			("enter_" + dlStDownloaded):   func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(e) },
+			("enter_" + dlStResetting):    func(e *fsm.Event) { onuDeviceEntry.enterResettingState(e) },
+		},
+	)
+	if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
+		logger.Error("MibDownloadFsm could not be instantiated!!")
+		// some specifc error treatment - or waiting for crash ???
+	}
+
+	onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.setBackend(cBasePathMibTemplateKvStore)
+	if onuDeviceEntry.mibTemplateKVStore == nil {
+		logger.Errorw("Failed to setup mibTemplateKVStore", log.Fields{"device-id": deviceID})
+	}
+
+	return &onuDeviceEntry
+}
+
+//start starts (logs) the omci agent
+func (oo *OnuDeviceEntry) start(ctx context.Context) error {
+	logger.Info("starting-OnuDeviceEntry")
+
+	oo.PDevOmciCC = newOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
+		oo.coreProxy, oo.adapterProxy)
+	if oo.PDevOmciCC == nil {
+		logger.Errorw("Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
+		return errors.New("could not create devOmciCc")
+	}
+
+	oo.started = true
+	logger.Info("OnuDeviceEntry-started")
+	return nil
+}
+
+//stop terminates the session
+func (oo *OnuDeviceEntry) stop(ctx context.Context) error {
+	logger.Info("stopping-OnuDeviceEntry")
+	oo.started = false
+	logger.Info("OnuDeviceEntry-stopped")
+	return nil
+}
+
+func (oo *OnuDeviceEntry) reboot(ctx context.Context) error {
+	logger.Info("reboot-OnuDeviceEntry")
+	if err := oo.PDevOmciCC.sendReboot(context.TODO(), ConstDefaultOmciTimeout, true, oo.omciRebootMessageReceivedChannel); err != nil {
+		logger.Errorw("onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
+		return err
+	}
+	logger.Info("OnuDeviceEntry-reboot")
+	return nil
+}
+
+func (oo *OnuDeviceEntry) waitForRebootResponse(responseChannel chan Message) error {
+	select {
+	case <-time.After(3 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw("Reboot timeout", log.Fields{"for device-id": oo.deviceID})
+		return errors.New("rebootTimeout")
+	case data := <-responseChannel:
+		switch data.Data.(OmciMessage).OmciMsg.MessageType {
+		case omci.RebootResponseType:
+			{
+				msgLayer := (*data.Data.(OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
+				if msgLayer == nil {
+					return errors.New("omci Msg layer could not be detected for RebootResponseType")
+				}
+				msgObj, msgOk := msgLayer.(*omci.GetResponse)
+				if !msgOk {
+					return errors.New("omci Msg layer could not be assigned for RebootResponseType")
+				}
+				logger.Debugw("CreateResponse Data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
+				if msgObj.Result != me.Success {
+					logger.Errorw("Omci RebootResponseType Error ", log.Fields{"Error": msgObj.Result})
+					// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+					return errors.New("omci RebootResponse Result Error indication")
+				}
+				return nil
+			}
+		}
+		logger.Warnw("Reboot response error", log.Fields{"for device-id": oo.deviceID})
+		return errors.New("unexpected OmciResponse type received")
+	}
+}
+
+//Relay the InSync message via Handler to Rw core - Status update
+func (oo *OnuDeviceEntry) transferSystemEvent(devEvent OnuDeviceEvent) {
+	logger.Debugw("relaying system-event", log.Fields{"Event": devEvent})
+	if devEvent == MibDatabaseSync {
+		if oo.devState < MibDatabaseSync { //devState has not been synced yet
+			oo.devState = MibDatabaseSync
+			go oo.baseDeviceHandler.deviceProcStatusUpdate(devEvent)
+			//TODO!!! device control: next step: start MIB capability verification from here ?!!!
+		} else {
+			logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
+		}
+	} else if devEvent == MibDownloadDone {
+		if oo.devState < MibDownloadDone { //devState has not been synced yet
+			oo.devState = MibDownloadDone
+			go oo.baseDeviceHandler.deviceProcStatusUpdate(devEvent)
+		} else {
+			logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
+		}
+	} else {
+		logger.Warnw("device-event not yet handled", log.Fields{"state": devEvent})
+	}
+}
diff --git a/internal/pkg/onuadaptercore/onu_list_access.go b/internal/pkg/onuadaptercore/onu_list_access.go
new file mode 100644
index 0000000..427cf19
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_list_access.go
@@ -0,0 +1,136 @@
+/*
+ * 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 adaptercoreonu
+
+import (
+	"encoding/json"
+	"io/ioutil"
+	"os"
+)
+
+// Jsonファイル名
+const jsonname = "/onu_list.json"
+
+// OnuStatus ONU状態
+type OnuStatus struct {
+	ID           string `json:"id"`
+	AdminState   string `json:"admin_state"`
+	OpeState     string `json:"ope_state"`
+	ConnectState string `json:"con_state"`
+	MacAddress   string `json:"mac_addr"`
+	RebootState  string `json:"reboot_state"`
+}
+
+//ReadOnuStatusList Jsonファイル読込み
+func ReadOnuStatusList() ([]OnuStatus, error) {
+	bytes, err := ioutil.ReadFile(os.Getenv("HOME") + jsonname)
+	if err != nil && os.IsNotExist(err) {
+		return nil, nil
+	}
+	var onuList []OnuStatus
+	if err := json.Unmarshal(bytes, &onuList); err != nil {
+		return nil, err
+	}
+	return onuList, nil
+}
+
+//WriteOnuStatusList Jsonファイル書き込み
+func WriteOnuStatusList(list []OnuStatus) error {
+	bytes, err := json.Marshal(list)
+	if err != nil {
+		return err
+	}
+	return ioutil.WriteFile(os.Getenv("HOME")+jsonname, bytes, 0644)
+}
+
+//AddOnu ONU追加
+func AddOnu(sts *OnuStatus) error {
+	list, err := ReadOnuStatusList()
+	if err != nil {
+		return err
+	}
+	if list == nil {
+		newList := []OnuStatus{*sts}
+		return WriteOnuStatusList(newList)
+	}
+	return WriteOnuStatusList(append(list, *sts))
+}
+
+//UpdateOnu ONU状態更新
+func UpdateOnu(upSts *OnuStatus) error {
+	list, err := ReadOnuStatusList()
+	if (err != nil) || (list == nil) {
+		return err
+	}
+	newList := []OnuStatus{}
+	for _, sts := range list {
+		if sts.ID == upSts.ID {
+			newList = append(newList, *upSts)
+		} else {
+			newList = append(newList, sts)
+		}
+	}
+	return WriteOnuStatusList(newList)
+}
+
+//RemoveOnu ONU削除
+func RemoveOnu(id string) error {
+	list, err := ReadOnuStatusList()
+	if (err != nil) || (list == nil) {
+		return err
+	}
+	newList := []OnuStatus{}
+	for _, sts := range list {
+		if sts.ID != id {
+			newList = append(newList, sts)
+		}
+	}
+	return WriteOnuStatusList(newList)
+}
+
+//GetOnuFromDeviceID ONU状態取得
+func GetOnuFromDeviceID(id string) (*OnuStatus, error) {
+	list, err := ReadOnuStatusList()
+	if err != nil {
+		return nil, err
+	}
+	if list == nil {
+		return nil, nil
+	}
+	for _, sts := range list {
+		if sts.ID != id {
+			return &sts, nil
+		}
+	}
+	return nil, nil
+}
+
+//GetOnuFromMacAddr ONU状態取得
+func GetOnuFromMacAddr(addr string) (*OnuStatus, error) {
+	list, err := ReadOnuStatusList()
+	if err != nil {
+		return nil, err
+	}
+	if list == nil {
+		return nil, nil
+	}
+	for _, sts := range list {
+		if sts.MacAddress == addr {
+			return &sts, nil
+		}
+	}
+	return nil, nil
+}
diff --git a/internal/pkg/onuadaptercore/onu_uni_port.go b/internal/pkg/onuadaptercore/onu_uni_port.go
new file mode 100644
index 0000000..9bfe1e9
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_uni_port.go
@@ -0,0 +1,180 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	vc "github.com/opencord/voltha-protos/v3/go/common"
+	of "github.com/opencord/voltha-protos/v3/go/openflow_13"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
+)
+
+type uniPortType uint8
+
+// UniPPTP Interface type - re-use values from G.988 TP type definition (directly used in OMCI!)
+const (
+	uniPPTP uniPortType = 1 // relates to PPTP
+	uniVEIP uniPortType = 11 // relates to VEIP
+)
+
+//onuUniPort structure holds information about the ONU attached Uni Ports
+type onuUniPort struct {
+	enabled    bool
+	name       string
+	portNo     uint32
+	portType   uniPortType
+	ofpPortNo  string
+	uniID      uint8
+	macBpNo    uint8
+	entityID   uint16
+	adminState vc.AdminState_Types
+	operState  vc.OperStatus_Types
+	pPort      *voltha.Port
+}
+
+//newOnuUniPort returns a new instance of a OnuUniPort
+func newOnuUniPort(aUniID uint8, aPortNo uint32, aInstNo uint16,
+	aPortType uniPortType) *onuUniPort {
+	logger.Infow("init-onuUniPort", log.Fields{"uniID": aUniID,
+		"portNo": aPortNo, "InstNo": aInstNo, "type": aPortType})
+	var onuUniPort onuUniPort
+	onuUniPort.enabled = false
+	onuUniPort.name = "uni-" + strconv.FormatUint(uint64(aPortNo), 10)
+	onuUniPort.portNo = aPortNo
+	onuUniPort.portType = aPortType
+	onuUniPort.ofpPortNo = onuUniPort.name
+	onuUniPort.uniID = aUniID
+	onuUniPort.macBpNo = aUniID + 1 //ensure >0 instanceNo
+	onuUniPort.entityID = aInstNo
+	onuUniPort.adminState = vc.AdminState_ENABLED //enabled per create
+	onuUniPort.operState = vc.OperStatus_UNKNOWN
+	onuUniPort.pPort = nil // to be set on create
+	return &onuUniPort
+}
+
+//createVolthaPort creates the Voltha port based on ONU UNI Port and informs the core about it
+func (oo *onuUniPort) createVolthaPort(apDeviceHandler *deviceHandler) error {
+	logger.Debugw("creating-voltha-uni-port", log.Fields{
+		"device-id": apDeviceHandler.device.Id, "portNo": oo.portNo})
+	name := apDeviceHandler.device.SerialNumber + "-" + strconv.FormatUint(uint64(oo.macBpNo), 10)
+
+	var macOctets [6]uint8
+	macOctets[5] = 0x08
+	macOctets[4] = uint8(apDeviceHandler.ponPortNumber >> 8)
+	macOctets[3] = uint8(apDeviceHandler.ponPortNumber)
+	macOctets[2] = uint8(oo.portNo >> 16)
+	macOctets[1] = uint8(oo.portNo >> 8)
+	macOctets[0] = uint8(oo.portNo)
+	onuEntry := apDeviceHandler.getOnuDeviceEntry(false)
+	if onuEntry == nil {
+		logger.Debugw("not-found-onu-device-entry", log.Fields{"error": "not found"})
+	} else {
+		if len(onuEntry.macAddress) == 12 {
+			for idx := 0; idx < 6; idx++ {
+				if v, err := strconv.ParseInt(onuEntry.macAddress[idx*2:(idx*2)+2], 16, 8); err == nil {
+					macOctets[5-idx] = uint8(v)
+				}
+			}
+		}
+	}
+	hwAddr := genMacFromOctets(macOctets)
+	ofHwAddr := macAddressToUint32Array(hwAddr)
+	capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
+	ofUniPortState := of.OfpPortState_OFPPS_LINK_DOWN
+	/* as the VOLTHA port create is only called directly after Uni Port create
+	   the OfPortOperState is always Down
+	   Note: this way the OfPortOperState won't ever change (directly in adapter)
+	   maybe that was already always the case, but looks a bit weird - to be kept in mind ...
+		if pUniPort.operState == vc.OperStatus_ACTIVE {
+			ofUniPortState = of.OfpPortState_OFPPS_LIVE
+		}
+	*/
+	logger.Debugw("ofPort values", log.Fields{
+		"forUniPortName": oo.name, "forMacBase": hwAddr,
+		"name": name, "hwAddr": ofHwAddr, "OperState": ofUniPortState})
+
+	pUniPort := &voltha.Port{
+		PortNo:     oo.portNo,
+		Label:      oo.name,
+		Type:       voltha.Port_ETHERNET_UNI,
+		AdminState: oo.adminState,
+		OperStatus: oo.operState,
+		// obviously empty peer setting
+		OfpPort: &of.OfpPort{
+			Name:       name,
+			HwAddr:     ofHwAddr,
+			Config:     0,
+			State:      uint32(ofUniPortState),
+			Curr:       capacity,
+			Advertised: capacity,
+			Peer:       capacity,
+			CurrSpeed:  uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+			MaxSpeed:   uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+		},
+	}
+	if pUniPort != nil {
+		if err := apDeviceHandler.coreProxy.PortCreated(context.TODO(),
+			apDeviceHandler.deviceID, pUniPort); err != nil {
+			logger.Fatalf("adding-uni-port: create-VOLTHA-Port-failed-%s", err)
+			return err
+		}
+		logger.Infow("Voltha onuUniPort-added", log.Fields{
+			"device-id": apDeviceHandler.device.Id, "PortNo": oo.portNo})
+		oo.pPort = pUniPort
+		oo.operState = vc.OperStatus_DISCOVERED
+	} else {
+		logger.Warnw("could not create Voltha UniPort", log.Fields{
+			"device-id": apDeviceHandler.device.Id, "PortNo": oo.portNo})
+		return errors.New("create Voltha UniPort failed")
+	}
+	return nil
+}
+
+//setOperState modifies OperState of the the UniPort
+func (oo *onuUniPort) setOperState(aNewOperState vc.OperStatus_Types) {
+	oo.operState = aNewOperState
+}
+
+// uni port related utility functions (so far only used here)
+func genMacFromOctets(aOctets [6]uint8) string {
+	return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
+		aOctets[5], aOctets[4], aOctets[3],
+		aOctets[2], aOctets[1], aOctets[0])
+}
+
+//copied from OLT Adapter: unify centrally ?
+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
+}
diff --git a/internal/pkg/onuadaptercore/onu_uni_tp.go b/internal/pkg/onuadaptercore/onu_uni_tp.go
new file mode 100644
index 0000000..09ae7bf
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_uni_tp.go
@@ -0,0 +1,681 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+	"sync"
+
+	"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"
+	tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
+)
+
+const cBasePathTechProfileKVStore = "service/voltha/technology_profiles"
+const cBasePathOnuKVStore = "service/voltha/openonu"
+
+//definitions for TechProfileProcessing - copied from OltAdapter:openolt_flowmgr.go
+//  could perhaps be defined more globally
+const (
+	binaryStringPrefix = "0b"
+)
+
+type resourceEntry int
+
+const (
+	cResourceGemPort resourceEntry = 1
+	cResourceTcont   resourceEntry = 2
+)
+
+type uniPersData struct {
+	PersUniID  uint32 `json:"uni_id"`
+	PersTpPath string `json:"tp_path"`
+}
+
+type onuPersistentData struct {
+	PersOnuID      uint32        `json:"onu_id"`
+	PersIntfID     uint32        `json:"intf_id"`
+	PersSnr        string        `json:"serial_number"`
+	PersAdminState string        `json:"admin_state"`
+	PersOperState  string        `json:"oper_state"`
+	PersUniTpPath  []uniPersData `json:"uni_config"`
+}
+
+type tTechProfileIndication struct {
+	techProfileType       string
+	techProfileID         uint16
+	techProfileConfigDone bool
+}
+
+type tcontParamStruct struct {
+	allocID     uint16
+	schedPolicy uint8
+}
+type gemPortParamStruct struct {
+	gemPortID       uint16
+	direction       uint8
+	gemPortEncState uint8
+	prioQueueIndex  uint8
+	pbitString      string
+	discardPolicy   string
+	queueSchedPolicy string
+	queueWeight      uint8
+}
+
+//refers to one tcont and its properties and all assigned GemPorts and their properties
+type tcontGemList struct {
+	tcontParams      tcontParamStruct
+	mapGemPortParams map[uint16]*gemPortParamStruct
+}
+
+//refers to all tcont and their Tcont/GemPort Parameters
+type tMapPonAniConfig map[uint16]*tcontGemList
+
+//onuUniTechProf structure holds information about the TechProfiles attached to Uni Ports of the ONU
+type onuUniTechProf struct {
+	deviceID                 string
+	baseDeviceHandler        *deviceHandler
+	tpProcMutex              sync.RWMutex
+	mapUniTpPath             map[uint32]string
+	sOnuPersistentData       onuPersistentData
+	techProfileKVStore       *db.Backend
+	onuKVStore               *db.Backend
+	onuKVStorePath           string
+	chTpConfigProcessingStep chan uint8
+	chTpKvProcessingStep     chan uint8
+	mapUniTpIndication       map[uint8]*tTechProfileIndication //use pointer values to ease assignments to the map
+	mapPonAniConfig          map[uint8]*tMapPonAniConfig       //per UNI: use pointer values to ease assignments to the map
+	pAniConfigFsm            *uniPonAniConfigFsm
+	procResult               error //error indication of processing
+	mutexTPState             sync.Mutex
+}
+
+//newOnuUniTechProf returns the instance of a OnuUniTechProf
+//(one instance per ONU/deviceHandler for all possible UNI's)
+func newOnuUniTechProf(ctx context.Context, aDeviceID string, aDeviceHandler *deviceHandler) *onuUniTechProf {
+	logger.Infow("init-OnuUniTechProf", log.Fields{"device-id": aDeviceID})
+	var onuTP onuUniTechProf
+	onuTP.deviceID = aDeviceID
+	onuTP.baseDeviceHandler = aDeviceHandler
+	onuTP.tpProcMutex = sync.RWMutex{}
+	onuTP.mapUniTpPath = make(map[uint32]string)
+	onuTP.sOnuPersistentData.PersUniTpPath = make([]uniPersData, 1)
+	onuTP.chTpConfigProcessingStep = make(chan uint8)
+	onuTP.chTpKvProcessingStep = make(chan uint8)
+	onuTP.mapUniTpIndication = make(map[uint8]*tTechProfileIndication)
+	onuTP.mapPonAniConfig = make(map[uint8]*tMapPonAniConfig)
+	onuTP.procResult = nil //default assumption processing done with success
+
+	onuTP.techProfileKVStore = aDeviceHandler.setBackend(cBasePathTechProfileKVStore)
+	if onuTP.techProfileKVStore == nil {
+		logger.Errorw("Can't access techProfileKVStore - no backend connection to service",
+			log.Fields{"device-id": aDeviceID, "service": cBasePathTechProfileKVStore})
+	}
+
+	onuTP.onuKVStorePath = onuTP.deviceID
+	onuTP.onuKVStore = aDeviceHandler.setBackend(cBasePathOnuKVStore)
+	if onuTP.onuKVStore == nil {
+		logger.Errorw("Can't access onuKVStore - no backend connection to service",
+			log.Fields{"device-id": aDeviceID, "service": cBasePathOnuKVStore})
+	}
+	return &onuTP
+}
+
+// lockTpProcMutex locks OnuUniTechProf processing mutex
+func (onuTP *onuUniTechProf) lockTpProcMutex() {
+	onuTP.tpProcMutex.Lock()
+}
+
+// unlockTpProcMutex unlocks OnuUniTechProf processing mutex
+func (onuTP *onuUniTechProf) unlockTpProcMutex() {
+	onuTP.tpProcMutex.Unlock()
+}
+
+// resetProcessingErrorIndication resets the internal error indication
+// need to be called before evaluation of any subsequent processing (given by waitForTpCompletion())
+func (onuTP *onuUniTechProf) resetProcessingErrorIndication() {
+	onuTP.procResult = nil
+}
+
+// updateOnuUniTpPath verifies and updates changes in the kvStore onuUniTpPath
+func (onuTP *onuUniTechProf) updateOnuUniTpPath(aUniID uint32, aPathString string) bool {
+	/* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
+	   as also the complete sequence is ensured to 'run to  completion' before some new request is accepted
+	   no specific concurrency protection to sOnuPersistentData is required here
+	*/
+	if existingPath, present := onuTP.mapUniTpPath[aUniID]; present {
+		// uni entry already exists
+		//logger.Debugw(" already exists", log.Fields{"for InstanceId": a_uniInstNo})
+		if existingPath != aPathString {
+			if aPathString == "" {
+				//existing entry to be deleted
+				logger.Debugw("UniTp path delete", log.Fields{
+					"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
+				delete(onuTP.mapUniTpPath, aUniID)
+			} else {
+				//existing entry to be modified
+				logger.Debugw("UniTp path modify", log.Fields{
+					"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
+				onuTP.mapUniTpPath[aUniID] = aPathString
+			}
+			return true
+		}
+		//entry already exists
+		logger.Debugw("UniTp path already exists", log.Fields{
+			"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
+		return false
+	}
+	if aPathString == "" {
+		//delete request in non-existing state , accept as no change
+		logger.Debugw("UniTp path already removed", log.Fields{
+			"device-id": onuTP.deviceID, "uniID": aUniID})
+		return false
+	}
+	logger.Debugw("New UniTp path set", log.Fields{
+		"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
+	onuTP.mapUniTpPath[aUniID] = aPathString
+	return true
+}
+
+func (onuTP *onuUniTechProf) waitForTpCompletion(cancel context.CancelFunc, wg *sync.WaitGroup) error {
+	defer cancel() //ensure termination of context (may be pro forma)
+	wg.Wait()
+	logger.Debug("some TechProfile Processing completed")
+	onuTP.tpProcMutex.Unlock() //allow further TP related processing
+	return onuTP.procResult
+}
+
+// configureUniTp checks existing tp resources to delete and starts the corresponding OMCI configuation of the UNI port
+// all possibly blocking processing must be run in background to allow for deadline supervision!
+// but take care on sequential background processing when needed (logical dependencies)
+//   use waitForTimeoutOrCompletion(ctx, chTpConfigProcessingStep, processingStep) for internal synchronization
+func (onuTP *onuUniTechProf) configureUniTp(ctx context.Context,
+	aUniID uint8, aPathString string, wg *sync.WaitGroup) {
+	defer wg.Done() //always decrement the waitGroup on return
+	logger.Debugw("configure the Uni according to TpPath", log.Fields{
+		"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
+
+	if onuTP.techProfileKVStore == nil {
+		logger.Debug("techProfileKVStore not set - abort")
+		onuTP.procResult = errors.New("techProfile config aborted: techProfileKVStore not set")
+		return
+	}
+
+	var pCurrentUniPort *onuUniPort
+	for _, uniPort := range onuTP.baseDeviceHandler.uniEntityMap {
+		// only if this port is validated for operState transfer
+		if uniPort.uniID == uint8(aUniID) {
+			pCurrentUniPort = uniPort
+			break //found - end search loop
+		}
+	}
+	if pCurrentUniPort == nil {
+		logger.Errorw("TechProfile configuration aborted: requested uniID not found in PortDB",
+			log.Fields{"device-id": onuTP.deviceID, "uniID": aUniID})
+		onuTP.procResult = errors.New("techProfile config aborted: requested uniID not found")
+		return
+	}
+
+	var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpConfigProcessingStep
+
+	/* if tcontMap  not empty {
+		go onuTP.deleteAniSideConfig(ctx, aUniID, processingStep)
+		if !onuTP.waitForTimeoutOrCompletion(ctx, chTpConfigProcessingStep, processingStep) {
+			//timeout or error detected
+			return
+		}
+		clear tcontMap
+	}
+
+	processingStep++
+	*/
+	go onuTP.readAniSideConfigFromTechProfile(ctx, aUniID, aPathString, processingStep)
+	if !onuTP.waitForTimeoutOrCompletion(ctx, onuTP.chTpConfigProcessingStep, processingStep) {
+		//timeout or error detected
+		logger.Debugw("tech-profile related configuration aborted on read",
+			log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID})
+		onuTP.procResult = errors.New("techProfile config aborted: tech-profile read issue")
+		return
+	}
+
+	processingStep++
+	if valuePA, existPA := onuTP.mapPonAniConfig[aUniID]; existPA {
+		if _, existTG := (*valuePA)[0]; existTG {
+			//Config data for this uni and and at least TCont Index 0 exist
+			go onuTP.setAniSideConfigFromTechProfile(ctx, aUniID, pCurrentUniPort, processingStep)
+			if !onuTP.waitForTimeoutOrCompletion(ctx, onuTP.chTpConfigProcessingStep, processingStep) {
+				//timeout or error detected
+				logger.Debugw("tech-profile related configuration aborted on set",
+					log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID})
+				onuTP.procResult = errors.New("techProfile config aborted: Omci AniSideConfig failed")
+				//this issue here means that the AniConfigFsm has not finished successfully
+				//which requires to reset it to allow for new usage, e.g. also on a different UNI
+				//(without that it would be reset on device down indication latest)
+				_ = onuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+				return
+			}
+		} else {
+			// strange: UNI entry exists, but no ANI data, maybe such situation should be cleared up (if observed)
+			logger.Debugw("no Tcont/Gem data for this UNI found - abort", log.Fields{
+				"device-id": onuTP.deviceID, "uniID": aUniID})
+			onuTP.procResult = errors.New("techProfile config aborted: no Tcont/Gem data found for this UNI")
+			return
+		}
+	} else {
+		logger.Debugw("no PonAni data for this UNI found - abort", log.Fields{
+			"device-id": onuTP.deviceID, "uniID": aUniID})
+		onuTP.procResult = errors.New("techProfile config aborted: no AniSide data found for this UNI")
+		return
+	}
+}
+
+func (onuTP *onuUniTechProf) updateOnuTpPathKvStore(ctx context.Context, wg *sync.WaitGroup) {
+	defer wg.Done()
+
+	if onuTP.onuKVStore == nil {
+		logger.Debugw("onuKVStore not set - abort", log.Fields{"device-id": onuTP.deviceID})
+		onuTP.procResult = errors.New("onu/tp-data update aborted: onuKVStore not set")
+		return
+	}
+	var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpKvProcessingStep
+	go onuTP.storePersistentData(ctx, processingStep)
+	if !onuTP.waitForTimeoutOrCompletion(ctx, onuTP.chTpKvProcessingStep, processingStep) {
+		//timeout or error detected
+		logger.Debugw("ONU/TP-data not written - abort", log.Fields{"device-id": onuTP.deviceID})
+		onuTP.procResult = errors.New("onu/tp-data update aborted: during writing process")
+		return
+	}
+}
+
+func (onuTP *onuUniTechProf) restoreFromOnuTpPathKvStore(ctx context.Context) error {
+	if onuTP.onuKVStore == nil {
+		logger.Debugw("onuKVStore not set - abort", log.Fields{"device-id": onuTP.deviceID})
+		return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", onuTP.deviceID))
+	}
+	if err := onuTP.restorePersistentData(ctx); err != nil {
+		logger.Debugw("ONU/TP-data not read - abort", log.Fields{"device-id": onuTP.deviceID})
+		return err
+	}
+	return nil
+}
+
+func (onuTP *onuUniTechProf) deleteOnuTpPathKvStore(ctx context.Context) error {
+	if onuTP.onuKVStore == nil {
+		logger.Debugw("onuKVStore not set - abort", log.Fields{"device-id": onuTP.deviceID})
+		return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", onuTP.deviceID))
+	}
+	if err := onuTP.deletePersistentData(ctx); err != nil {
+		logger.Debugw("ONU/TP-data not read - abort", log.Fields{"device-id": onuTP.deviceID})
+		return err
+	}
+	return nil
+}
+
+// deleteTpResource removes Resources from the ONU's specified Uni
+func (onuTP *onuUniTechProf) deleteTpResource(ctx context.Context,
+	aUniID uint32, aPathString string, aResource resourceEntry, aEntryID uint32,
+	wg *sync.WaitGroup) {
+	defer wg.Done()
+	logger.Debugw("this would remove TP resources from ONU's UNI", log.Fields{
+		"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString, "Resource": aResource})
+	/*
+		var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpConfigProcessingStep
+		go onuTp.deleteAniResource(ctx, processingStep)
+		if !onuTP.waitForTimeoutOrCompletion(ctx, chTpConfigProcessingStep, processingStep) {
+			//timeout or error detected
+			return
+		}
+	*/
+}
+
+/* internal methods *********************/
+
+func (onuTP *onuUniTechProf) storePersistentData(ctx context.Context, aProcessingStep uint8) {
+
+	onuTP.sOnuPersistentData.PersOnuID = onuTP.baseDeviceHandler.pOnuIndication.OnuId
+	onuTP.sOnuPersistentData.PersIntfID = onuTP.baseDeviceHandler.pOnuIndication.IntfId
+	onuTP.sOnuPersistentData.PersSnr = onuTP.baseDeviceHandler.pOnuOmciDevice.serialNumber
+	onuTP.sOnuPersistentData.PersAdminState = "up"
+	onuTP.sOnuPersistentData.PersOperState = "active"
+
+	onuTP.sOnuPersistentData.PersUniTpPath = onuTP.sOnuPersistentData.PersUniTpPath[:0]
+
+	for k, v := range onuTP.mapUniTpPath {
+		onuTP.sOnuPersistentData.PersUniTpPath =
+			append(onuTP.sOnuPersistentData.PersUniTpPath, uniPersData{PersUniID: k, PersTpPath: v})
+	}
+	logger.Debugw("Update ONU/TP-data in KVStore", log.Fields{"device-id": onuTP.deviceID, "onuTP.sOnuPersistentData": onuTP.sOnuPersistentData})
+
+	Value, err := json.Marshal(onuTP.sOnuPersistentData)
+	if err != nil {
+		logger.Errorw("unable to marshal ONU/TP-data", log.Fields{"onuTP.sOnuPersistentData": onuTP.sOnuPersistentData,
+			"device-id": onuTP.deviceID, "err": err})
+		onuTP.chTpKvProcessingStep <- 0 //error indication
+		return
+	}
+	err = onuTP.onuKVStore.Put(ctx, onuTP.onuKVStorePath, Value)
+	if err != nil {
+		logger.Errorw("unable to write ONU/TP-data into KVstore", log.Fields{"device-id": onuTP.deviceID, "err": err})
+		onuTP.chTpKvProcessingStep <- 0 //error indication
+		return
+	}
+	onuTP.chTpKvProcessingStep <- aProcessingStep //done
+}
+
+func (onuTP *onuUniTechProf) restorePersistentData(ctx context.Context) error {
+
+	onuTP.mapUniTpPath = make(map[uint32]string)
+	onuTP.sOnuPersistentData = onuPersistentData{0, 0, "", "", "", make([]uniPersData, 0)}
+
+	Value, err := onuTP.onuKVStore.Get(ctx, onuTP.onuKVStorePath)
+	if err == nil {
+		if Value != nil {
+			logger.Debugw("ONU/TP-data read",
+				log.Fields{"Key": Value.Key, "device-id": onuTP.deviceID})
+			tpTmpBytes, _ := kvstore.ToByte(Value.Value)
+
+			if err = json.Unmarshal(tpTmpBytes, &onuTP.sOnuPersistentData); err != nil {
+				logger.Errorw("unable to unmarshal ONU/TP-data", log.Fields{"error": err, "device-id": onuTP.deviceID})
+				return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU/TP-data-%s", onuTP.deviceID))
+			}
+			logger.Debugw("ONU/TP-data", log.Fields{"onuTP.sOnuPersistentData": onuTP.sOnuPersistentData,
+				"device-id": onuTP.deviceID})
+
+			for _, uniData := range onuTP.sOnuPersistentData.PersUniTpPath {
+				onuTP.mapUniTpPath[uniData.PersUniID] = uniData.PersTpPath
+			}
+			logger.Debugw("TpPath map", log.Fields{"onuTP.mapUniTpPath": onuTP.mapUniTpPath,
+				"device-id": onuTP.deviceID})
+		} else {
+			logger.Errorw("no ONU/TP-data found", log.Fields{"path": onuTP.onuKVStorePath, "device-id": onuTP.deviceID})
+			return fmt.Errorf(fmt.Sprintf("no-ONU/TP-data-found-%s", onuTP.deviceID))
+		}
+	} else {
+		logger.Errorw("unable to read from KVstore", log.Fields{"device-id": onuTP.deviceID})
+		return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", onuTP.deviceID))
+	}
+	return nil
+}
+
+func (onuTP *onuUniTechProf) deletePersistentData(ctx context.Context) error {
+
+	logger.Debugw("delete ONU/TP-data in KVStore", log.Fields{"device-id": onuTP.deviceID})
+	err := onuTP.onuKVStore.Delete(ctx, onuTP.onuKVStorePath)
+	if err != nil {
+		logger.Errorw("unable to delete in KVstore", log.Fields{"device-id": onuTP.deviceID, "err": err})
+		return fmt.Errorf(fmt.Sprintf("unable-delete-in-KVstore-%s", onuTP.deviceID))
+	}
+	return nil
+}
+
+func (onuTP *onuUniTechProf) readAniSideConfigFromTechProfile(
+	ctx context.Context, aUniID uint8, aPathString string, aProcessingStep uint8) {
+	var tpInst tp.TechProfile
+
+	subStringSlice := strings.Split(aPathString, "/")
+	if len(subStringSlice) <= 2 {
+		logger.Errorw("invalid path name format",
+			log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+		onuTP.chTpConfigProcessingStep <- 0 //error indication
+		return
+	}
+
+	if _, existTP := onuTP.mapUniTpIndication[aUniID]; existTP {
+		logger.Warnw("Some active profile entry at reading new TechProfile",
+			log.Fields{"path": aPathString, "device-id": onuTP.deviceID,
+				"UniId": aUniID, "wrongProfile": onuTP.mapUniTpIndication[aUniID].techProfileID})
+		//delete on the mapUniTpIndication map not needed, just overwritten later
+		//delete on the PonAniConfig map should be safe, even if not existing
+		delete(onuTP.mapPonAniConfig, aUniID)
+	} else {
+		// this is normal processing
+		onuTP.mapUniTpIndication[aUniID] = &tTechProfileIndication{} //need to assign some (empty) struct memory first!
+	}
+
+	onuTP.mapUniTpIndication[aUniID].techProfileType = subStringSlice[0]
+	profID, err := strconv.ParseUint(subStringSlice[1], 10, 32)
+	if err != nil {
+		logger.Errorw("invalid ProfileId from path",
+			log.Fields{"ParseErr": err})
+		onuTP.chTpConfigProcessingStep <- 0 //error indication
+		return
+	}
+
+	onuTP.mapUniTpIndication[aUniID].techProfileID = uint16(profID)
+	logger.Debugw("tech-profile path indications",
+		log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID,
+			"profType": onuTP.mapUniTpIndication[aUniID].techProfileType,
+			"profID":   onuTP.mapUniTpIndication[aUniID].techProfileID})
+
+	Value, err := onuTP.techProfileKVStore.Get(ctx, aPathString)
+	if err == nil {
+		if Value != nil {
+			logger.Debugw("tech-profile read",
+				log.Fields{"Key": Value.Key, "device-id": onuTP.deviceID})
+			tpTmpBytes, _ := kvstore.ToByte(Value.Value)
+
+			if err = json.Unmarshal(tpTmpBytes, &tpInst); err != nil {
+				logger.Errorw("TechProf - Failed to unmarshal tech-profile into tpInst",
+					log.Fields{"error": err, "device-id": onuTP.deviceID})
+				onuTP.chTpConfigProcessingStep <- 0 //error indication
+				return
+			}
+			logger.Debugw("TechProf - tpInst", log.Fields{"tpInst": tpInst})
+			// access examples
+			logger.Debugw("TechProf content", log.Fields{"Name": tpInst.Name,
+				"MaxGemPayloadSize":                tpInst.InstanceCtrl.MaxGemPayloadSize,
+				"DownstreamGemDiscardmaxThreshold": tpInst.DownstreamGemPortAttributeList[0].DiscardConfig.MaxThreshold})
+		} else {
+			logger.Errorw("No tech-profile found",
+				log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+			onuTP.chTpConfigProcessingStep <- 0 //error indication
+			return
+		}
+	} else {
+		logger.Errorw("kvstore-get failed for path",
+			log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+		onuTP.chTpConfigProcessingStep <- 0 //error indication
+		return
+	}
+
+	localMapGemPortParams := make(map[uint16]*gemPortParamStruct)
+	localMapGemPortParams[0] = &gemPortParamStruct{}
+	localMapPonAniConfig := make(map[uint16]*tcontGemList)
+	localMapPonAniConfig[0] = &tcontGemList{tcontParamStruct{}, localMapGemPortParams}
+	onuTP.mapPonAniConfig[aUniID] = (*tMapPonAniConfig)(&localMapPonAniConfig)
+
+	(*(onuTP.mapPonAniConfig[aUniID]))[0].tcontParams.allocID = uint16(tpInst.UsScheduler.AllocID)
+	if tpInst.UsScheduler.QSchedPolicy == "StrictPrio" {
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].tcontParams.schedPolicy = 1 //for the moment fixed value acc. G.988 //TODO: defines!
+	} else {
+		//default profile defines "Hybrid" - which probably comes down to WRR with some weigthts for SP
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].tcontParams.schedPolicy = 2 //for G.988 WRR
+	}
+	loNumGemPorts := tpInst.NumGemPorts
+	loGemPortRead := false
+	for pos, content := range tpInst.UpstreamGemPortAttributeList {
+		if uint32(pos) == loNumGemPorts {
+			logger.Debugw("PonAniConfig abort GemPortList - GemList exceeds set NumberOfGemPorts",
+				log.Fields{"device-id": onuTP.deviceID, "index": pos, "NumGem": loNumGemPorts})
+			break
+		}
+		if pos == 0 {
+			//at least one upstream GemPort should always exist (else traffic profile makes no sense)
+			loGemPortRead = true
+		} else {
+			//for all further GemPorts we need to extend the mapGemPortParams
+			(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)] = &gemPortParamStruct{}
+		}
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].gemPortID =
+			uint16(content.GemportID)
+		//direction can be correlated later with Downstream list,
+		//  for now just assume bidirectional (upstream never exists alone)
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].direction = 3 //as defined in G.988
+		// expected Prio-Queue values 0..7 with 7 for highest PrioQueue, QueueIndex=Prio = 0..7
+		if 7 < content.PriorityQueue {
+			logger.Errorw("PonAniConfig reject on GemPortList - PrioQueue value invalid",
+				log.Fields{"device-id": onuTP.deviceID, "index": pos, "PrioQueue": content.PriorityQueue})
+			//remove PonAniConfig  as done so far, delete map should be safe, even if not existing
+			delete(onuTP.mapPonAniConfig, aUniID)
+			onuTP.chTpConfigProcessingStep <- 0 //error indication
+			return
+		}
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].prioQueueIndex =
+			uint8(content.PriorityQueue)
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].pbitString =
+			strings.TrimPrefix(content.PbitMap, binaryStringPrefix)
+		if content.AesEncryption == "True" {
+			(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].gemPortEncState = 1
+		} else {
+			(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].gemPortEncState = 0
+		}
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].discardPolicy =
+			content.DiscardPolicy
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].queueSchedPolicy =
+			content.SchedulingPolicy
+		//'GemWeight' looks strange in default profile, for now we just copy the weight to first queue
+		(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].queueWeight =
+			uint8(content.Weight)
+	}
+	if !loGemPortRead {
+		logger.Errorw("PonAniConfig reject - no GemPort could be read from TechProfile",
+			log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+		//remove PonAniConfig  as done so far, delete map should be safe, even if not existing
+		delete(onuTP.mapPonAniConfig, aUniID)
+		onuTP.chTpConfigProcessingStep <- 0 //error indication
+		return
+	}
+
+	logger.Debugw("PonAniConfig read from TechProfile", log.Fields{
+		"device-id": onuTP.deviceID,
+		"AllocId":   (*(onuTP.mapPonAniConfig[aUniID]))[0].tcontParams.allocID})
+	for gemIndex, gemEntry := range (*(onuTP.mapPonAniConfig[0]))[0].mapGemPortParams {
+		logger.Debugw("PonAniConfig read from TechProfile", log.Fields{
+			"GemIndex":        gemIndex,
+			"GemPort":         gemEntry.gemPortID,
+			"QueueScheduling": gemEntry.queueSchedPolicy})
+	}
+
+	onuTP.chTpConfigProcessingStep <- aProcessingStep //done
+}
+
+func (onuTP *onuUniTechProf) setAniSideConfigFromTechProfile(
+	ctx context.Context, aUniID uint8, apCurrentUniPort *onuUniPort, aProcessingStep uint8) {
+
+	if onuTP.pAniConfigFsm == nil {
+		onuTP.createAniConfigFsm(aUniID, apCurrentUniPort, OmciAniConfigDone, aProcessingStep)
+	} else { //AniConfigFsm already init
+		onuTP.runAniConfigFsm(aProcessingStep)
+	}
+}
+
+func (onuTP *onuUniTechProf) waitForTimeoutOrCompletion(
+	ctx context.Context, aChTpProcessingStep <-chan uint8, aProcessingStep uint8) bool {
+	select {
+	case <-ctx.Done():
+		logger.Warnw("processing not completed in-time: force release of TpProcMutex!",
+			log.Fields{"device-id": onuTP.deviceID, "error": ctx.Err()})
+		return false
+	case rxStep := <-aChTpProcessingStep:
+		if rxStep == aProcessingStep {
+			return true
+		}
+		//all other values are not accepted - including 0 for error indication
+		logger.Warnw("Invalid processing step received: abort and force release of TpProcMutex!",
+			log.Fields{"device-id": onuTP.deviceID,
+				"wantedStep": aProcessingStep, "haveStep": rxStep})
+		return false
+	}
+}
+
+// createUniLockFsm initializes and runs the AniConfig FSM to transfer the OMCI related commands for ANI side configuration
+func (onuTP *onuUniTechProf) createAniConfigFsm(aUniID uint8,
+	apCurrentUniPort *onuUniPort, devEvent OnuDeviceEvent, aProcessingStep uint8) {
+	logger.Debugw("createAniConfigFsm", log.Fields{"device-id": onuTP.deviceID})
+	chAniConfigFsm := make(chan Message, 2048)
+	pDevEntry := onuTP.baseDeviceHandler.getOnuDeviceEntry(true)
+	if pDevEntry == nil {
+		logger.Errorw("No valid OnuDevice - aborting", log.Fields{"device-id": onuTP.deviceID})
+		return
+	}
+	pAniCfgFsm := newUniPonAniConfigFsm(pDevEntry.PDevOmciCC, apCurrentUniPort, onuTP,
+		pDevEntry.pOnuDB, onuTP.mapUniTpIndication[aUniID].techProfileID, devEvent,
+		"AniConfigFsm", onuTP.deviceID, chAniConfigFsm)
+	if pAniCfgFsm != nil {
+		onuTP.pAniConfigFsm = pAniCfgFsm
+		onuTP.runAniConfigFsm(aProcessingStep)
+	} else {
+		logger.Errorw("AniConfigFSM could not be created - abort!!", log.Fields{"device-id": onuTP.deviceID})
+	}
+}
+
+// runAniConfigFsm starts the AniConfig FSM to transfer the OMCI related commands for  ANI side configuration
+func (onuTP *onuUniTechProf) runAniConfigFsm(aProcessingStep uint8) {
+	/*  Uni related ANI config procedure -
+	 ***** should run via 'aniConfigDone' state and generate the argument requested event *****
+	 */
+	pACStatemachine := onuTP.pAniConfigFsm.pAdaptFsm.pFsm
+	if pACStatemachine != nil {
+		if pACStatemachine.Is(aniStDisabled) {
+			//FSM init requirement to get informed abou FSM completion! (otherwise timeout of the TechProf config)
+			onuTP.pAniConfigFsm.setFsmCompleteChannel(onuTP.chTpConfigProcessingStep, aProcessingStep)
+			if err := pACStatemachine.Event(aniEvStart); err != nil {
+				logger.Warnw("AniConfigFSM: can't start", log.Fields{"err": err})
+				// maybe try a FSM reset and then again ... - TODO!!!
+			} else {
+				/***** AniConfigFSM started */
+				logger.Debugw("AniConfigFSM started", log.Fields{
+					"state": pACStatemachine.Current(), "device-id": onuTP.deviceID})
+			}
+		} else {
+			logger.Warnw("wrong state of AniConfigFSM - want: disabled", log.Fields{
+				"have": pACStatemachine.Current(), "device-id": onuTP.deviceID})
+			// maybe try a FSM reset and then again ... - TODO!!!
+		}
+	} else {
+		logger.Errorw("AniConfigFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": onuTP.deviceID})
+		// maybe try a FSM reset and then again ... - TODO!!!
+	}
+}
+
+// setConfigDone sets the requested techProfile config state (if possible)
+func (onuTP *onuUniTechProf) setConfigDone(aUniID uint8, aState bool) {
+	if _, existTP := onuTP.mapUniTpIndication[aUniID]; existTP {
+		onuTP.mutexTPState.Lock()
+		onuTP.mapUniTpIndication[aUniID].techProfileConfigDone = aState
+		onuTP.mutexTPState.Unlock()
+	} //else: the state is just ignored (does not exist)
+}
+
+// getTechProfileDone checks if the Techprofile processing with the requested TechProfile ID was done
+func (onuTP *onuUniTechProf) getTechProfileDone(aUniID uint8, aTpID uint16) bool {
+	if _, existTP := onuTP.mapUniTpIndication[aUniID]; existTP {
+		if onuTP.mapUniTpIndication[aUniID].techProfileID == aTpID {
+			onuTP.mutexTPState.Lock()
+			defer onuTP.mutexTPState.Unlock()
+			return onuTP.mapUniTpIndication[aUniID].techProfileConfigDone
+		}
+	}
+	return false
+}
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
new file mode 100644
index 0000000..a8a84d4
--- /dev/null
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -0,0 +1,428 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"sync"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
+	"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	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"
+
+	"test.internal/openadapter/internal/pkg/config"
+)
+
+//OpenONUAC structure holds the ONU core information
+type OpenONUAC struct {
+	deviceHandlers              map[string]*deviceHandler
+	coreProxy                   adapterif.CoreProxy
+	adapterProxy                adapterif.AdapterProxy
+	eventProxy                  adapterif.EventProxy
+	kafkaICProxy                kafka.InterContainerProxy
+	kvClient                    kvstore.Client
+	config                      *config.AdapterFlags
+	numOnus                     int
+	KVStoreHost                 string
+	KVStorePort                 int
+	KVStoreType                 string
+	KVStoreTimeout              time.Duration
+	exitChannel                 chan int
+	HeartbeatCheckInterval      time.Duration
+	HeartbeatFailReportInterval time.Duration
+	AcceptIncrementalEvto       bool
+	lockDeviceHandlersMap sync.RWMutex
+	pSupportedFsms        *OmciDeviceFsms
+}
+
+//NewOpenONUAC returns a new instance of OpenONU_AC
+func NewOpenONUAC(ctx context.Context, kafkaICProxy kafka.InterContainerProxy,
+	coreProxy adapterif.CoreProxy, adapterProxy adapterif.AdapterProxy,
+	eventProxy adapterif.EventProxy, kvClient kvstore.Client, cfg *config.AdapterFlags) *OpenONUAC {
+	var openOnuAc OpenONUAC
+	openOnuAc.exitChannel = make(chan int, 1)
+	openOnuAc.deviceHandlers = make(map[string]*deviceHandler)
+	openOnuAc.kafkaICProxy = kafkaICProxy
+	openOnuAc.config = cfg
+	openOnuAc.numOnus = cfg.OnuNumber
+	openOnuAc.coreProxy = coreProxy
+	openOnuAc.adapterProxy = adapterProxy
+	openOnuAc.eventProxy = eventProxy
+	openOnuAc.kvClient = kvClient
+	openOnuAc.KVStoreHost = cfg.KVStoreHost
+	openOnuAc.KVStorePort = cfg.KVStorePort
+	openOnuAc.KVStoreType = cfg.KVStoreType
+	openOnuAc.KVStoreTimeout = cfg.KVStoreTimeout
+	openOnuAc.HeartbeatCheckInterval = cfg.HeartbeatCheckInterval
+	openOnuAc.HeartbeatFailReportInterval = cfg.HeartbeatFailReportInterval
+	openOnuAc.AcceptIncrementalEvto = cfg.AccIncrEvto
+	openOnuAc.lockDeviceHandlersMap = sync.RWMutex{}
+
+	openOnuAc.pSupportedFsms = &OmciDeviceFsms{
+		"mib-synchronizer": {
+			//mibSyncFsm,        // Implements the MIB synchronization state machine
+			mibDbVolatileDictImpl, // Implements volatile ME MIB database
+			//true,                  // Advertise events on OpenOMCI event bus
+			cMibAuditDelayImpl, // Time to wait between MIB audits.  0 to disable audits.
+			// map[string]func() error{
+			// 	"mib-upload":    onuDeviceEntry.MibUploadTask,
+			// 	"mib-template":  onuDeviceEntry.MibTemplateTask,
+			// 	"get-mds":       onuDeviceEntry.GetMdsTask,
+			// 	"mib-audit":     onuDeviceEntry.GetMdsTask,
+			// 	"mib-resync":    onuDeviceEntry.MibResyncTask,
+			// 	"mib-reconcile": onuDeviceEntry.MibReconcileTask,
+			// },
+		},
+	}
+
+	return &openOnuAc
+}
+
+//Start starts (logs) the adapter
+func (oo *OpenONUAC) Start(ctx context.Context) error {
+	logger.Info("starting-openonu-adapter")
+	logger.Info("openonu-adapter-started")
+	return nil
+}
+
+/*
+//stop terminates the session
+func (oo *OpenONUAC) stop(ctx context.Context) error {
+	logger.Info("stopping-device-manager")
+	oo.exitChannel <- 1
+	logger.Info("device-manager-stopped")
+	return nil
+}
+*/
+
+func (oo *OpenONUAC) addDeviceHandlerToMap(ctx context.Context, agent *deviceHandler) {
+	oo.lockDeviceHandlersMap.Lock()
+	defer oo.lockDeviceHandlersMap.Unlock()
+	if _, exist := oo.deviceHandlers[agent.deviceID]; !exist {
+		oo.deviceHandlers[agent.deviceID] = agent
+		oo.deviceHandlers[agent.deviceID].start(ctx)
+	}
+}
+
+/*
+func (oo *OpenONUAC) deleteDeviceHandlerToMap(agent *deviceHandler) {
+	oo.lockDeviceHandlersMap.Lock()
+	defer oo.lockDeviceHandlersMap.Unlock()
+	delete(oo.deviceHandlers, agent.deviceID)
+}
+*/
+
+func (oo *OpenONUAC) getDeviceHandler(deviceID string) *deviceHandler {
+	oo.lockDeviceHandlersMap.Lock()
+	defer oo.lockDeviceHandlersMap.Unlock()
+	if agent, ok := oo.deviceHandlers[deviceID]; ok {
+		return agent
+	}
+	return nil
+}
+
+// Adapter interface required methods ############## begin #########
+// #################################################################
+
+// for original content compare: (needs according deviceHandler methods)
+// /voltha-openolt-adapter/adaptercore/openolt.go
+
+// Adopt_device creates a new device handler if not present already and then adopts the device
+func (oo *OpenONUAC) Adopt_device(device *voltha.Device) error {
+	if device == nil {
+		logger.Warn("voltha-device-is-nil")
+		return errors.New("nil-device")
+	}
+	ctx := context.Background()
+	logger.Infow("adopt-device", log.Fields{"device-id": 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(ctx, handler)
+		go handler.adoptOrReconcileDevice(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 *OpenONUAC) Get_ofp_device_info(device *voltha.Device) (*ic.SwitchCapability, error) {
+	logger.Errorw("device-handler-not-set", log.Fields{"device-id": device.Id})
+	return nil, errors.New("device-handler-not-set")
+}
+
+//Get_ofp_port_info returns OFP port information for the given device
+//200630: method removed as per [VOL-3202]: OF port info is now to be delivered within UniPort create
+// cmp changes in onu_uni_port.go::CreateVolthaPort()
+
+//Process_inter_adapter_message sends messages to a target device (between adapters)
+func (oo *OpenONUAC) Process_inter_adapter_message(msg *ic.InterAdapterMessage) error {
+	logger.Debugw("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id,
+		"msgProxyDeviceId": msg.Header.ProxyDeviceId, "msgToDeviceId": msg.Header.ToDeviceId})
+
+	targetDevice := msg.Header.ToDeviceId
+	if handler := oo.getDeviceHandler(targetDevice); handler != nil {
+		/* 200724: modification towards synchronous implementation - possible errors within processing shall be
+		 * 	 in the accordingly delayed response, some timing effect might result in Techprofile processing for multiple UNI's
+		 */
+		return handler.processInterAdapterMessage(msg)
+		/* so far the processing has been in background with according commented error treatment restrictions:
+		go handler.ProcessInterAdapterMessage(msg)
+		// error treatment might be more sophisticated
+		// by now let's just accept the message on 'communication layer'
+		// message content problems have to be evaluated then in the handler
+		//   and are by now not reported to the calling party (to force what reaction there?)
+		return nil
+		*/
+	}
+	logger.Warnw("no handler found for received Inter-Proxy-message", log.Fields{
+		"msgToDeviceId": targetDevice})
+	return fmt.Errorf(fmt.Sprintf("handler-not-found-%s", targetDevice))
+}
+
+//Adapter_descriptor not implemented
+func (oo *OpenONUAC) Adapter_descriptor() error {
+	return errors.New("unImplemented")
+}
+
+//Device_types unimplemented
+func (oo *OpenONUAC) Device_types() (*voltha.DeviceTypes, error) {
+	return nil, errors.New("unImplemented")
+}
+
+//Health  returns unimplemented
+func (oo *OpenONUAC) Health() (*voltha.HealthStatus, error) {
+	return nil, errors.New("unImplemented")
+}
+
+//Reconcile_device is called once when the adapter needs to re-create device - usually on core restart
+func (oo *OpenONUAC) Reconcile_device(device *voltha.Device) error {
+	if device == nil {
+		logger.Warn("voltha-device-is-nil")
+		return errors.New("nil-device")
+	}
+	ctx := context.Background()
+	logger.Infow("Reconcile_device", log.Fields{"device-id": 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(ctx, handler)
+		handler.device = device
+		handler.reconciling = true
+		go handler.adoptOrReconcileDevice(ctx, handler.device)
+		// reconcilement will be continued after onu-device entry is added
+	} else {
+		return fmt.Errorf(fmt.Sprintf("device-already-reconciled-or-active-%s", device.Id))
+	}
+	return nil
+}
+
+//Abandon_device unimplemented
+func (oo *OpenONUAC) Abandon_device(device *voltha.Device) error {
+	return errors.New("unImplemented")
+}
+
+var disableOnuFunc bool = true
+
+//Disable_device disables the given device
+func (oo *OpenONUAC) Disable_device(device *voltha.Device) error {
+	logger.Debugw("Disable_device", log.Fields{"device-id": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		if err := handler.sendMsgToOlt(context.TODO(), "disable", nil); err != nil {
+			logger.Debugw("Disable_device", log.Fields{"error": err})
+		}
+		if disableOnuFunc {
+			return nil
+		}
+		//go handler.disableDevice(device)
+		//return nil
+	}
+	logger.Warnw("no handler found for device-disable", log.Fields{"device-id": device.Id})
+	return fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
+}
+
+//Reenable_device enables the onu device after disable
+func (oo *OpenONUAC) Reenable_device(device *voltha.Device) error {
+	logger.Debugw("Reenable_device", log.Fields{"device-id": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		if err := handler.sendMsgToOlt(context.TODO(), "reenable", nil); err != nil {
+			logger.Debugw("Disable_device", log.Fields{"error": err})
+		}
+		if disableOnuFunc {
+			return nil
+		}
+		go handler.reEnableDevice(device)
+		return nil
+	}
+	logger.Warnw("no handler found for device-reenable", log.Fields{"device-id": device.Id})
+	return fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
+}
+
+//Reboot_device reboots the given device
+func (oo *OpenONUAC) Reboot_device(device *voltha.Device) error {
+	logger.Debugw("Reboot-device", log.Fields{"device-id": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		go handler.rebootDevice(device)
+		return nil
+	}
+	logger.Warnw("no handler found for device-reboot", log.Fields{"device-id": device.Id})
+	return fmt.Errorf(fmt.Sprintf("handler-not-found-#{device.Id}"))
+}
+
+//Self_test_device unimplemented
+func (oo *OpenONUAC) Self_test_device(device *voltha.Device) error {
+	return errors.New("unImplemented")
+}
+
+// Delete_device deletes the given device
+func (oo *OpenONUAC) Delete_device(device *voltha.Device) error {
+	logger.Debugw("Delete_device", log.Fields{"device-id": device.Id})
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		if err := handler.deleteDevice(device); err != nil {
+			return err
+		}
+	} else {
+		logger.Warnw("no handler found for device-reconcilement", log.Fields{"device-id": device.Id})
+		return fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
+	}
+	return nil
+}
+
+//Get_device_details unimplemented
+func (oo *OpenONUAC) Get_device_details(device *voltha.Device) error {
+	return errors.New("unImplemented")
+}
+
+//Update_flows_bulk returns
+func (oo *OpenONUAC) Update_flows_bulk(device *voltha.Device, flows *voltha.Flows, groups *voltha.FlowGroups, flowMetadata *voltha.FlowMetadata) error {
+	return errors.New("unImplemented")
+}
+
+var disableUpdateFlows = true
+
+//Update_flows_incrementally updates (add/remove) the flows on a given device
+func (oo *OpenONUAC) Update_flows_incrementally(device *voltha.Device,
+	flows *openflow_13.FlowChanges, groups *openflow_13.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
+	if disableUpdateFlows {
+		return nil
+	}
+	if device.ConnectStatus != voltha.ConnectStatus_REACHABLE ||
+		device.AdminState != voltha.AdminState_ENABLED {
+		logger.Warnw("device disabled or offline - skipping flow-update", log.Fields{"deviceId": device.Id})
+		return errors.New("non-matching device state")
+	}
+
+	if groups.ToAdd != nil && groups.ToAdd.Items != nil {
+		logger.Debugw("Update-flow-incr: group add not supported (ignored)", log.Fields{"deviceId": device.Id})
+	}
+	if groups.ToRemove != nil && groups.ToRemove.Items != nil {
+		logger.Debugw("Update-flow-incr: group remove not supported (ignored)", log.Fields{"deviceId": device.Id})
+	}
+	if groups.ToUpdate != nil && groups.ToUpdate.Items != nil {
+		logger.Debugw("Update-flow-incr: group update not supported (ignored)", log.Fields{"deviceId": device.Id})
+	}
+
+	if handler := oo.getDeviceHandler(device.Id); handler != nil {
+		err := handler.FlowUpdateIncremental(flows, groups, flowMetadata)
+		return err
+	}
+	logger.Warnw("no handler found for incremental flow update", log.Fields{"deviceId": device.Id})
+	return fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
+}
+
+//Update_pm_config returns PmConfigs nil or error
+func (oo *OpenONUAC) Update_pm_config(device *voltha.Device, pmConfigs *voltha.PmConfigs) error {
+	return errors.New("unImplemented")
+}
+
+//Receive_packet_out sends packet out to the device
+func (oo *OpenONUAC) Receive_packet_out(deviceID string, egressPortNo int, packet *openflow_13.OfpPacketOut) error {
+	return errors.New("unImplemented")
+}
+
+//Suppress_event unimplemented
+func (oo *OpenONUAC) Suppress_event(filter *voltha.EventFilter) error {
+	return errors.New("unImplemented")
+}
+
+//Unsuppress_event  unimplemented
+func (oo *OpenONUAC) Unsuppress_event(filter *voltha.EventFilter) error {
+	return errors.New("unImplemented")
+}
+
+//Download_image unimplemented
+func (oo *OpenONUAC) Download_image(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, errors.New("unImplemented")
+}
+
+//Get_image_download_status unimplemented
+func (oo *OpenONUAC) Get_image_download_status(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, errors.New("unImplemented")
+}
+
+//Cancel_image_download unimplemented
+func (oo *OpenONUAC) Cancel_image_download(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, errors.New("unImplemented")
+}
+
+//Activate_image_update unimplemented
+func (oo *OpenONUAC) Activate_image_update(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, errors.New("unImplemented")
+}
+
+//Revert_image_update unimplemented
+func (oo *OpenONUAC) Revert_image_update(device *voltha.Device, request *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	return nil, errors.New("unImplemented")
+}
+
+// Enable_port to Enable PON/NNI interface - seems not to be used/required according to python code
+func (oo *OpenONUAC) Enable_port(deviceID string, port *voltha.Port) error {
+	return errors.New("unImplemented")
+}
+
+// Disable_port to Disable pon/nni interface  - seems not to be used/required according to python code
+func (oo *OpenONUAC) Disable_port(deviceID string, port *voltha.Port) error {
+	return errors.New("unImplemented")
+}
+
+//Child_device_lost - unimplemented
+//needed for if update >= 3.1.x
+func (oo *OpenONUAC) Child_device_lost(deviceID string, pPortNo uint32, onuID uint32) error {
+	return errors.New("unImplemented")
+}
+
+// Start_omci_test unimplemented
+func (oo *OpenONUAC) Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*voltha.TestResponse, error) {
+	return nil, errors.New("unImplemented")
+}
+
+// Get_ext_value - unimplemented
+func (oo *OpenONUAC) Get_ext_value(deviceID string, device *voltha.Device, valueparam voltha.ValueType_Type) (*voltha.ReturnValues, error) {
+	return nil, errors.New("unImplemented")
+}
+
+// Adapter interface required methods ################ end #########
+// #################################################################
diff --git a/internal/pkg/onuadaptercore/openonuimpl.go b/internal/pkg/onuadaptercore/openonuimpl.go
new file mode 100644
index 0000000..15109cb
--- /dev/null
+++ b/internal/pkg/onuadaptercore/openonuimpl.go
@@ -0,0 +1,101 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"errors"
+)
+
+/*
+OpenOmciAgentDefaults = {
+    'mib-synchronizer': {
+        'state-machine': MibSynchronizer,  # Implements the MIB synchronization state machine
+        'database': MibDbVolatileDict,     # Implements volatile ME MIB database
+        # 'database': MibDbExternal,         # Implements persistent ME MIB database
+        'advertise-events': True,          # Advertise events on OpenOMCI event bus
+        'audit-delay': 60,                 # Time to wait between MIB audits.  0 to disable audits.
+        'tasks': {
+            'mib-upload': MibUploadTask,
+            'mib-template': MibTemplateTask,
+            'get-mds': GetMdsTask,
+            'mib-audit': GetMdsTask,
+            'mib-resync': MibResyncTask,
+            'mib-reconcile': MibReconcileTask
+        }
+    },
+    'omci-capabilities': {
+        'state-machine': OnuOmciCapabilities,   # Implements OMCI capabilities state machine
+        'advertise-events': False,              # Advertise events on OpenOMCI event bus
+        'tasks': {
+            'get-capabilities': OnuCapabilitiesTask # Get supported ME and Commands
+        }
+    },
+    'performance-intervals': {
+        'state-machine': PerformanceIntervals,  # Implements PM Intervals State machine
+        'advertise-events': False,              # Advertise events on OpenOMCI event bus
+        'tasks': {
+            'sync-time': SyncTimeTask,
+            'collect-data': IntervalDataTask,
+            'create-pm': OmciCreatePMRequest,
+            'delete-pm': OmciDeletePMRequest,
+        },
+    },
+    'alarm-synchronizer': {
+        'state-machine': AlarmSynchronizer,    # Implements the Alarm sync state machine
+        'database': AlarmDbExternal,           # For any State storage needs
+        'advertise-events': True,              # Advertise events on OpenOMCI event bus
+        'tasks': {
+            'alarm-resync': AlarmResyncTask
+        }
+     },
+    'image_downloader': {
+        'state-machine': ImageDownloadeSTM,
+        'advertise-event': True,
+        'tasks': {
+            'download-file': FileDownloadTask
+        }
+    },
+    'image_upgrader': {
+        'state-machine': OmciSoftwareImageDownloadSTM,
+        'advertise-event': True,
+        'tasks': {
+            'omci_upgrade_task': OmciSwImageUpgradeTask
+        }
+    }
+    # 'image_activator': {
+    #     'state-machine': OmciSoftwareImageActivateSTM,
+    #     'advertise-event': True,
+    # }
+}
+*/
+
+// do not use MibAudit
+const cMibAuditDelayImpl = 0
+
+//suppose global methods per adapter ...
+func mibDbVolatileDictImpl() error {
+	logger.Debug("MibVolatileDict-called")
+	return errors.New("not_implemented")
+}
+
+/*
+func alarmDbDictImpl() error {
+	logger.Debug("AlarmDb-called")
+	return errors.New("not_implemented")
+}
+*/
diff --git a/internal/pkg/onuadaptercore/platform.go b/internal/pkg/onuadaptercore/platform.go
new file mode 100644
index 0000000..fa1ff6e
--- /dev/null
+++ b/internal/pkg/onuadaptercore/platform.go
@@ -0,0 +1,287 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+//Attention: this file is more or less a coopy of file olt_platform.go from the voltha-openolt-adapter
+// which includes system wide definitions and thus normally should be stored more centrally (within some voltha libs)!!
+
+/*=====================================================================
+
+@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 (
+	bitsForUniID = 4
+	bitsForONUID = 8
+	bitsForPONID = 8
+	/*
+		// Number of bits to differentiate between UNI and NNI Logical Port
+		bitsForUNINNIDiff = 1
+	*/
+	maxOnusPerPon = (1 << bitsForONUID)
+	maxPonsPerOlt = (1 << bitsForPONID)
+	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)
+	*/
+)
+
+//Mask to indicate which possibly active ONU UNI state  is really reported to the core
+// compare python code - at the moment restrict active state to the first ONU UNI port
+// check is limited to max 16 uni ports - cmp above UNI limit!!!
+var activeUniPortStateUpdateMask = 0x0001
+
+/*
+//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(intfID)
+	if limit > maxPonsPerOlt {
+		logger.Warn("Warning: exceeded the MAX pons per OLT")
+	}
+	limit = int(onuID)
+	if limit > maxOnusPerPon {
+		logger.Warn("Warning: exceeded the MAX ONUS per PON")
+	}
+	limit = int(uniID)
+	if limit > maxUnisPerOnu {
+		logger.Warn("Warning: exceeded the MAX UNIS per ONU")
+	}
+	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 {
+		logger.Errorw("NNIPortNumber is not in valid range", log.Fields{"portNum": portNum})
+		return uint32(0), errors.New("invalid-port-range") //olterrors.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, errors.New("notFound: pon-interface (flowDirection)")
+		// olterrors.NewErrNotFound("pon-interface", log.Fields{"flow-direction": flowDirection}, nil)
+	}
+
+	ponIntf = intfIDFromUniPortNum(uniPortNo)
+	onuID = onuIDFromUniPortNum(uniPortNo)
+	uniID = uniIDFromPortNum(uniPortNo)
+
+	logger.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/onuadaptercore/status.go b/internal/pkg/onuadaptercore/status.go
new file mode 100644
index 0000000..d43fd57
--- /dev/null
+++ b/internal/pkg/onuadaptercore/status.go
@@ -0,0 +1,54 @@
+/*
+ * 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 adaptercoreonu
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
+	"github.com/opencord/voltha-protos/v3/go/common"
+)
+
+var startWatchStatus bool = false
+
+//WatchStatus ...
+func WatchStatus(ctx context.Context, cp adapterif.CoreProxy) {
+	if startWatchStatus {
+		return
+	}
+	startWatchStatus = true
+	logger.Debug(ctx, fmt.Sprintf("Start WatchStatus()"))
+	ticker := time.NewTicker(1000 * time.Millisecond)
+	prevOnuList := make(map[string]OnuStatus)
+	for range ticker.C {
+		onuList, err := ReadOnuStatusList()
+		if err == nil {
+			for _, onu := range onuList {
+				current, ok := prevOnuList[onu.MacAddress]
+				if !ok || onu.OpeState != current.OpeState || onu.ConnectState != current.ConnectState {
+					con := common.ConnectStatus_Types(common.ConnectStatus_Types_value[onu.ConnectState])
+					ope := common.OperStatus_Types(common.OperStatus_Types_value[onu.OpeState])
+					err2 := cp.DeviceStateUpdate(ctx, onu.ID, con, ope)
+					logger.Debug(ctx, fmt.Sprintf("WatchStatus() update: %s, OpeState: %v, ConnectState: %v, error: %v",
+						onu.ID, onu.OpeState, onu.ConnectState, err2))
+					prevOnuList[onu.MacAddress] = onu
+				}
+			}
+		}
+	}
+}
diff --git a/internal/pkg/onuadaptercore/uniportadmin.go b/internal/pkg/onuadaptercore/uniportadmin.go
new file mode 100644
index 0000000..36b7fb7
--- /dev/null
+++ b/internal/pkg/onuadaptercore/uniportadmin.go
@@ -0,0 +1,373 @@
+/*
+ * 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 adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+	"context"
+	"errors"
+	"time"
+
+	"github.com/looplab/fsm"
+
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+//lockStateFsm defines the structure for the state machine to lock/unlock the ONU UNI ports via OMCI
+type lockStateFsm struct {
+	pOmciCC                  *omciCC
+	adminState               bool
+	requestEvent             OnuDeviceEvent
+	omciLockResponseReceived chan bool //seperate channel needed for checking UNI port OMCi message responses
+	pAdaptFsm                *AdapterFsm
+}
+
+const (
+	uniEvStart         = "uniEvStart"
+	uniEvStartAdmin    = "uniEvStartAdmin"
+	uniEvRxUnisResp    = "uniEvRxUnisResp"
+	uniEvRxOnugResp    = "uniEvRxOnugResp"
+	uniEvTimeoutSimple = "uniEvTimeoutSimple"
+	uniEvTimeoutUnis   = "uniEvTimeoutUnis"
+	uniEvReset         = "uniEvReset"
+	uniEvRestart       = "uniEvRestart"
+)
+const (
+	uniStDisabled    = "uniStDisabled"
+	uniStStarting    = "uniStStarting"
+	uniStSettingUnis = "uniStSettingUnis"
+	uniStSettingOnuG = "uniStSettingOnuG"
+	uniStAdminDone   = "uniStAdminDone"
+	uniStResetting   = "uniStResetting"
+)
+
+//newLockStateFsm is the 'constructor' for the state machine to lock/unlock the ONU UNI ports via OMCI
+func newLockStateFsm(apDevOmciCC *omciCC, aAdminState bool, aRequestEvent OnuDeviceEvent,
+	aName string, aDeviceID string, aCommChannel chan Message) *lockStateFsm {
+	instFsm := &lockStateFsm{
+		pOmciCC:      apDevOmciCC,
+		adminState:   aAdminState,
+		requestEvent: aRequestEvent,
+	}
+	instFsm.pAdaptFsm = NewAdapterFsm(aName, aDeviceID, aCommChannel)
+	if instFsm.pAdaptFsm == nil {
+		logger.Errorw("LockStateFsm's AdapterFsm could not be instantiated!!", log.Fields{
+			"device-id": aDeviceID})
+		return nil
+	}
+	if aAdminState { //port locking requested
+		instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
+			uniStDisabled,
+			fsm.Events{
+
+				{Name: uniEvStart, Src: []string{uniStDisabled}, Dst: uniStStarting},
+
+				{Name: uniEvStartAdmin, Src: []string{uniStStarting}, Dst: uniStSettingUnis},
+				// the settingUnis state is used for multi ME config for all UNI related ports
+				// maybe such could be reflected in the state machine as well (port number parametrized)
+				// but that looks not straightforward here - so we keep it simple here for the beginning(?)
+				{Name: uniEvRxUnisResp, Src: []string{uniStSettingUnis}, Dst: uniStSettingOnuG},
+				{Name: uniEvRxOnugResp, Src: []string{uniStSettingOnuG}, Dst: uniStAdminDone},
+
+				{Name: uniEvTimeoutSimple, Src: []string{uniStSettingOnuG}, Dst: uniStStarting},
+				{Name: uniEvTimeoutUnis, Src: []string{uniStSettingUnis}, Dst: uniStStarting},
+
+				{Name: uniEvReset, Src: []string{uniStStarting, uniStSettingOnuG, uniStSettingUnis,
+					uniStAdminDone}, Dst: uniStResetting},
+				// exceptional treatment for all states except uniStResetting
+				{Name: uniEvRestart, Src: []string{uniStStarting, uniStSettingOnuG, uniStSettingUnis,
+					uniStAdminDone, uniStResetting}, Dst: uniStDisabled},
+			},
+
+			fsm.Callbacks{
+				"enter_state":                 func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
+				("enter_" + uniStStarting):    func(e *fsm.Event) { instFsm.enterAdminStartingState(e) },
+				("enter_" + uniStSettingOnuG): func(e *fsm.Event) { instFsm.enterSettingOnuGState(e) },
+				("enter_" + uniStSettingUnis): func(e *fsm.Event) { instFsm.enterSettingUnisState(e) },
+				("enter_" + uniStAdminDone):   func(e *fsm.Event) { instFsm.enterAdminDoneState(e) },
+				("enter_" + uniStResetting):   func(e *fsm.Event) { instFsm.enterResettingState(e) },
+			},
+		)
+	} else { //port unlocking requested
+		instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
+			uniStDisabled,
+			fsm.Events{
+
+				{Name: uniEvStart, Src: []string{uniStDisabled}, Dst: uniStStarting},
+
+				{Name: uniEvStartAdmin, Src: []string{uniStStarting}, Dst: uniStSettingOnuG},
+				{Name: uniEvRxOnugResp, Src: []string{uniStSettingOnuG}, Dst: uniStSettingUnis},
+				// the settingUnis state is used for multi ME config for all UNI related ports
+				// maybe such could be reflected in the state machine as well (port number parametrized)
+				// but that looks not straightforward here - so we keep it simple here for the beginning(?)
+				{Name: uniEvRxUnisResp, Src: []string{uniStSettingUnis}, Dst: uniStAdminDone},
+
+				{Name: uniEvTimeoutSimple, Src: []string{uniStSettingOnuG}, Dst: uniStStarting},
+				{Name: uniEvTimeoutUnis, Src: []string{uniStSettingUnis}, Dst: uniStStarting},
+
+				{Name: uniEvReset, Src: []string{uniStStarting, uniStSettingOnuG, uniStSettingUnis,
+					uniStAdminDone}, Dst: uniStResetting},
+				// exceptional treatment for all states except uniStResetting
+				{Name: uniEvRestart, Src: []string{uniStStarting, uniStSettingOnuG, uniStSettingUnis,
+					uniStAdminDone, uniStResetting}, Dst: uniStDisabled},
+			},
+
+			fsm.Callbacks{
+				"enter_state":                 func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
+				("enter_" + uniStStarting):    func(e *fsm.Event) { instFsm.enterAdminStartingState(e) },
+				("enter_" + uniStSettingOnuG): func(e *fsm.Event) { instFsm.enterSettingOnuGState(e) },
+				("enter_" + uniStSettingUnis): func(e *fsm.Event) { instFsm.enterSettingUnisState(e) },
+				("enter_" + uniStAdminDone):   func(e *fsm.Event) { instFsm.enterAdminDoneState(e) },
+				("enter_" + uniStResetting):   func(e *fsm.Event) { instFsm.enterResettingState(e) },
+			},
+		)
+	}
+	if instFsm.pAdaptFsm.pFsm == nil {
+		logger.Errorw("LockStateFsm's Base FSM could not be instantiated!!", log.Fields{
+			"device-id": aDeviceID})
+		return nil
+	}
+
+	logger.Infow("LockStateFsm created", log.Fields{"device-id": aDeviceID})
+	return instFsm
+}
+
+//setSuccessEvent modifies the requested event notified on success
+//assumption is that this is only called in the disabled (idle) state of the FSM, hence no sem protection required
+func (oFsm *lockStateFsm) setSuccessEvent(aEvent OnuDeviceEvent) {
+	oFsm.requestEvent = aEvent
+}
+
+func (oFsm *lockStateFsm) enterAdminStartingState(e *fsm.Event) {
+	logger.Debugw("LockStateFSM start", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.pAdaptFsm.deviceID})
+	if oFsm.omciLockResponseReceived == nil {
+		oFsm.omciLockResponseReceived = make(chan bool)
+		logger.Debug("LockStateFSM - OMCI UniLock RxChannel defined")
+	} else {
+		// as we may 're-use' this instance of FSM and the connected channel
+		// make sure there is no 'lingering' request in the already existing channel:
+		// (simple loop sufficient as we are the only receiver)
+		for len(oFsm.omciLockResponseReceived) > 0 {
+			<-oFsm.omciLockResponseReceived
+		}
+	}
+	go oFsm.processOmciLockMessages()
+
+	pLockStateAFsm := oFsm.pAdaptFsm
+	if pLockStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(uniEvStartAdmin)
+			}
+		}(pLockStateAFsm)
+	}
+}
+
+func (oFsm *lockStateFsm) enterSettingOnuGState(e *fsm.Event) {
+	var omciAdminState uint8 = 1 //default locked
+	if !oFsm.adminState {
+		omciAdminState = 0
+	}
+	logger.Debugw("LockStateFSM Tx Set::ONU-G:admin", log.Fields{
+		"omciAdmin": omciAdminState, "in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	requestedAttributes := me.AttributeValueMap{"AdministrativeState": omciAdminState}
+	meInstance := oFsm.pOmciCC.sendSetOnuGLS(context.TODO(), ConstDefaultOmciTimeout, true,
+		requestedAttributes, oFsm.pAdaptFsm.commChan)
+	oFsm.pOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *lockStateFsm) enterSettingUnisState(e *fsm.Event) {
+	logger.Infow("LockStateFSM - starting PPTP config loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID, "LockState": oFsm.adminState})
+	go oFsm.performUniPortAdminSet()
+}
+
+func (oFsm *lockStateFsm) enterAdminDoneState(e *fsm.Event) {
+	logger.Debugw("LockStateFSM", log.Fields{"send notification to core in State": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	oFsm.pOmciCC.pBaseDeviceHandler.deviceProcStatusUpdate(oFsm.requestEvent)
+	pLockStateAFsm := oFsm.pAdaptFsm
+	if pLockStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(uniEvReset)
+			}
+		}(pLockStateAFsm)
+	}
+}
+
+func (oFsm *lockStateFsm) enterResettingState(e *fsm.Event) {
+	logger.Debugw("LockStateFSM resetting", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	pLockStateAFsm := oFsm.pAdaptFsm
+	if pLockStateAFsm != nil {
+		// abort running message processing
+		fsmAbortMsg := Message{
+			Type: TestMsg,
+			Data: TestMessage{
+				TestMessageVal: AbortMessageProcessing,
+			},
+		}
+		pLockStateAFsm.commChan <- fsmAbortMsg
+
+		//try to restart the FSM to 'disabled'
+		// see DownloadedState: decouple event transfer
+		go func(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				_ = a_pAFsm.pFsm.Event(uniEvRestart)
+			}
+		}(pLockStateAFsm)
+	}
+}
+
+func (oFsm *lockStateFsm) processOmciLockMessages( /*ctx context.Context*/ ) {
+	logger.Debugw("Start LockStateFsm Msg processing", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+loop:
+	for {
+		// case <-ctx.Done():
+		// 	logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.pAdaptFsm.deviceID})
+		// 	break loop
+		message, ok := <-oFsm.pAdaptFsm.commChan
+		if !ok {
+			logger.Info("LockStateFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+			// but then we have to ensure a restart of the FSM as well - as exceptional procedure
+			_ = oFsm.pAdaptFsm.pFsm.Event(uniEvRestart)
+			break loop
+		}
+		logger.Debugw("LockStateFsm Rx Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+
+		switch message.Type {
+		case TestMsg:
+			msg, _ := message.Data.(TestMessage)
+			if msg.TestMessageVal == AbortMessageProcessing {
+				logger.Infow("LockStateFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+				break loop
+			}
+			logger.Warnw("LockStateFsm unknown TestMessage", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "MessageVal": msg.TestMessageVal})
+		case OMCI:
+			msg, _ := message.Data.(OmciMessage)
+			oFsm.handleOmciLockStateMessage(msg)
+		default:
+			logger.Warn("LockStateFsm Rx unknown message", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
+				"message.Type": message.Type})
+		}
+	}
+	logger.Infow("End LockStateFsm Msg processing", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+}
+
+func (oFsm *lockStateFsm) handleOmciLockStateMessage(msg OmciMessage) {
+	logger.Debugw("Rx OMCI LockStateFsm Msg", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID,
+		"msgType": msg.OmciMsg.MessageType})
+
+	if msg.OmciMsg.MessageType == omci.SetResponseType {
+		msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
+		if msgLayer == nil {
+			logger.Error("LockStateFsm - Omci Msg layer could not be detected for SetResponse")
+			return
+		}
+		msgObj, msgOk := msgLayer.(*omci.SetResponse)
+		if !msgOk {
+			logger.Error("LockStateFsm - Omci Msg layer could not be assigned for SetResponse")
+			return
+		}
+		logger.Debugw("LockStateFsm SetResponse Data", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "data-fields": msgObj})
+		if msgObj.Result != me.Success {
+			logger.Errorw("LockStateFsm - Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+			// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+			return
+		}
+		// compare comments above for CreateResponse (apply also here ...)
+		if msgObj.EntityClass == oFsm.pOmciCC.pLastTxMeInstance.GetClassID() &&
+			msgObj.EntityInstance == oFsm.pOmciCC.pLastTxMeInstance.GetEntityID() {
+			//store the created ME into DB //TODO??? obviously the Python code does not store the config ...
+			// if, then something like:
+			//oFsm.pOnuDB.StoreMe(msgObj)
+
+			switch oFsm.pOmciCC.pLastTxMeInstance.GetName() {
+			case "OnuG":
+				{ // let the FSM proceed ...
+					_ = oFsm.pAdaptFsm.pFsm.Event(uniEvRxOnugResp)
+				}
+			case "UniG", "VEIP":
+				{ // let the PPTP init proceed by stopping the wait function
+					oFsm.omciLockResponseReceived <- true
+				}
+			}
+		}
+	} else {
+		logger.Errorw("LockStateFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
+		return
+	}
+}
+
+func (oFsm *lockStateFsm) performUniPortAdminSet() {
+	var omciAdminState uint8 = 1 //default locked
+	if !oFsm.adminState {
+		omciAdminState = 0
+	}
+	requestedAttributes := me.AttributeValueMap{"AdministrativeState": omciAdminState}
+
+	for uniNo, uniPort := range oFsm.pOmciCC.pBaseDeviceHandler.uniEntityMap {
+		logger.Debugw("Setting PPTP admin state", log.Fields{
+			"device-id": oFsm.pAdaptFsm.deviceID, "for PortNo": uniNo})
+
+		var meInstance *me.ManagedEntity
+		if uniPort.portType == uniPPTP {
+			meInstance = oFsm.pOmciCC.sendSetUniGLS(context.TODO(), uniPort.entityID, ConstDefaultOmciTimeout,
+				true, requestedAttributes, oFsm.pAdaptFsm.commChan)
+			oFsm.pOmciCC.pLastTxMeInstance = meInstance
+		} else if uniPort.portType == uniVEIP {
+			meInstance = oFsm.pOmciCC.sendSetVeipLS(context.TODO(), uniPort.entityID, ConstDefaultOmciTimeout,
+				true, requestedAttributes, oFsm.pAdaptFsm.commChan)
+			oFsm.pOmciCC.pLastTxMeInstance = meInstance
+		} else {
+			logger.Warnw("Unsupported PPTP type - skip",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "Port": uniNo})
+			continue
+		}
+
+		//verify response
+		err := oFsm.waitforOmciResponse(meInstance)
+		if err != nil {
+			logger.Errorw("PPTP Admin State set failed, aborting LockState set!",
+				log.Fields{"device-id": oFsm.pAdaptFsm.deviceID, "Port": uniNo})
+			_ = oFsm.pAdaptFsm.pFsm.Event(uniEvReset)
+			return
+		}
+	} //for all UNI ports
+	logger.Infow("PPTP config loop finished", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	_ = oFsm.pAdaptFsm.pFsm.Event(uniEvRxUnisResp)
+}
+
+func (oFsm *lockStateFsm) waitforOmciResponse(apMeInstance *me.ManagedEntity) error {
+	select {
+	case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw("LockStateFSM uni-set timeout", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+		return errors.New("lockStateFsm uni-set timeout")
+	case success := <-oFsm.omciLockResponseReceived:
+		if success {
+			logger.Debug("LockStateFSM uni-set response received")
+			return nil
+		}
+		// should not happen so far
+		logger.Warnw("LockStateFSM uni-set response error", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+		return errors.New("lockStateFsm uni-set responseError")
+	}
+}
