[VOL-3380] Functional area specific logging

Change-Id: I67414da013d8fc82827fcdb69d4f8a34040625d3
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
new file mode 100755
index 0000000..ebf8de8
--- /dev/null
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -0,0 +1,992 @@
+/*
+ * 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 mib provides the utilities for managing the onu mib
+package mib
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"sync"
+	"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/v7/pkg/db"
+	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
+	vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+
+	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
+	devdb "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
+	"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
+)
+
+// events of MibUpload FSM
+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"
+)
+
+// states of MibUpload FSM
+const (
+	UlStDisabled               = "UlStDisabled"
+	UlStStarting               = "UlStStarting"
+	UlStResettingMib           = "UlStResettingMib"
+	UlStGettingVendorAndSerial = "UlStGettingVendorAndSerial"
+	UlStGettingEquipmentID     = "UlStGettingEquipmentID"
+	UlStGettingFirstSwVersion  = "UlStGettingFirstSwVersion"
+	UlStGettingSecondSwVersion = "UlStGettingSecondSwVersion"
+	UlStGettingMacAddress      = "UlStGettingMacAddress"
+	UlStGettingMibTemplate     = "UlStGettingMibTemplate"
+	UlStUploading              = "UlStUploading"
+	UlStUploadDone             = "UlStUploadDone"
+	UlStInSync                 = "UlStInSync"
+	UlStExaminingMds           = "UlStExaminingMds"
+	UlStResynchronizing        = "UlStResynchronizing"
+	UlStExaminingMdsSuccess    = "UlStExaminingMdsSuccess"
+	UlStAuditing               = "UlStAuditing"
+	UlStReAuditing             = "UlStReAuditing"
+	UlStOutOfSync              = "UlStOutOfSync"
+)
+
+// CMibUlFsmIdleState - TODO: add comment
+const CMibUlFsmIdleState = UlStInSync
+
+// events of MibDownload FSM
+const (
+	DlEvStart         = "DlEvStart"
+	DlEvCreateGal     = "DlEvCreateGal"
+	DlEvRxGalResp     = "DlEvRxGalResp"
+	DlEvRxOnu2gResp   = "DlEvRxOnu2gResp"
+	DlEvRxBridgeResp  = "DlEvRxBridgeResp"
+	DlEvTimeoutSimple = "DlEvTimeoutSimple"
+	DlEvTimeoutBridge = "DlEvTimeoutBridge"
+	DlEvReset         = "DlEvReset"
+	DlEvRestart       = "DlEvRestart"
+)
+
+// states of MibDownload FSM
+const (
+	DlStDisabled     = "DlStDisabled"
+	DlStStarting     = "DlStStarting"
+	DlStCreatingGal  = "DlStCreatingGal"
+	DlStSettingOnu2g = "DlStSettingOnu2g"
+	DlStBridgeInit   = "DlStBridgeInit"
+	DlStDownloaded   = "DlStDownloaded"
+	DlStResetting    = "DlStResetting"
+)
+
+// CMibDlFsmIdleState - TODO: add comment
+const CMibDlFsmIdleState = DlStDisabled
+
+const (
+	// NOTE that this hardcoded to service/voltha as the MIB template is shared across stacks
+	cBasePathMibTemplateKvStore = "service/voltha/omci_mibs/go_templates"
+	cSuffixMibTemplateKvStore   = "%s/%s/%s"
+	cBasePathOnuKVStore         = "%s/openonu"
+)
+
+const cEmptyMacAddrString = "000000000000"
+const cEmptySerialNumberString = "0000000000000000"
+
+type uniPersConfig struct {
+	PersUniID      uint8                   `json:"uni_id"`
+	PersTpPathMap  map[uint8]string        `json:"PersTpPathMap"` // tp-id to tp-path map
+	PersFlowParams []cmn.UniVlanFlowParams `json:"flow_params"`   //as defined in omci_ani_config.go
+}
+
+type onuPersistentData struct {
+	PersOnuID              uint32            `json:"onu_id"`
+	PersIntfID             uint32            `json:"intf_id"`
+	PersSerialNumber       string            `json:"serial_number"`
+	PersMacAddress         string            `json:"mac_address"`
+	PersVendorID           string            `json:"vendor_id"`
+	PersEquipmentID        string            `json:"equipment_id"`
+	PersActiveSwVersion    string            `json:"active_sw_version"`
+	PersAdminState         string            `json:"admin_state"`
+	PersOperState          string            `json:"oper_state"`
+	PersUniUnlockDone      bool              `json:"uni_unlock_done"`
+	PersUniDisableDone     bool              `json:"uni_disable_done"`
+	PersMibAuditInterval   time.Duration     `json:"mib_audit_interval"`
+	PersMibLastDbSync      uint32            `json:"mib_last_db_sync"`
+	PersMibDataSyncAdpt    uint8             `json:"mib_data_sync_adpt"`
+	PersUniConfig          []uniPersConfig   `json:"uni_config"`
+	PersAlarmAuditInterval time.Duration     `json:"alarm_audit_interval"`
+	PersTcontMap           map[uint16]uint16 `json:"tcont_map"` //alloc-id to me-instance-id map
+}
+
+// OnuDeviceEntry - ONU device info and FSM events.
+type OnuDeviceEntry struct {
+	deviceID                   string
+	baseDeviceHandler          cmn.IdeviceHandler
+	pOpenOnuAc                 cmn.IopenONUAC
+	pOnuTP                     cmn.IonuUniTechProf
+	coreClient                 *vgrpc.Client
+	PDevOmciCC                 *cmn.OmciCC
+	pOnuDB                     *devdb.OnuDeviceDB
+	mibTemplateKVStore         *db.Backend
+	MutexPersOnuConfig         sync.RWMutex
+	SOnuPersistentData         onuPersistentData
+	reconcilingFlows           bool
+	mutexReconcilingFlowsFlag  sync.RWMutex
+	chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
+	mibTemplatePath            string
+	mutexOnuKVStore            sync.RWMutex
+	onuKVStore                 *db.Backend
+	onuKVStorePath             string
+	mutexOnuKVStoreProcResult  sync.RWMutex
+	onuKVStoreProcResult       error //error indication of processing
+	chOnuKvProcessingStep      chan uint8
+	mutexOnuSwImageIndications sync.RWMutex
+	onuSwImageIndications      cmn.SswImageIndications
+	MutexOnuImageStatus        sync.RWMutex
+	POnuImageStatus            *swupg.OnuImageStatus
+	//lockDeviceEntries           sync.RWMutex
+	mibDbClass    func(context.Context) error
+	supportedFsms cmn.OmciDeviceFsms
+	devState      cmn.OnuDeviceEvent
+	// Audit and MDS
+	mibAuditInterval   time.Duration
+	alarmAuditInterval time.Duration
+	// TODO: periodical mib resync will be implemented with story VOL-3792
+	//mibNextDbResync uint32
+
+	// for mibUpload
+	PMibUploadFsm          *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
+	mutexLastTxParamStruct sync.RWMutex
+	lastTxParamStruct      sLastTxMeParameter
+	// for mibDownload
+	PMibDownloadFsm *cmn.AdapterFsm //could be handled dynamically and more general as pcmn.AdapterFsm - perhaps later
+	//remark: general usage of pAdapterFsm would require generalization of CommChan  usage and internal event setting
+	//  within the FSM event procedures
+	mutexPLastTxMeInstance           sync.RWMutex
+	pLastTxMeInstance                *me.ManagedEntity
+	omciMessageReceived              chan bool        //seperate channel needed by DownloadFsm
+	omciRebootMessageReceivedChannel chan cmn.Message // channel needed by reboot request
+
+	mutexTcontMap sync.RWMutex
+}
+
+//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, cc *vgrpc.Client, dh cmn.IdeviceHandler,
+	openonu cmn.IopenONUAC) *OnuDeviceEntry {
+	var onuDeviceEntry OnuDeviceEntry
+	onuDeviceEntry.deviceID = dh.GetDeviceID()
+	logger.Debugw(ctx, "init-onuDeviceEntry", log.Fields{"device-id": onuDeviceEntry.deviceID})
+	onuDeviceEntry.baseDeviceHandler = dh
+	onuDeviceEntry.pOpenOnuAc = openonu
+	onuDeviceEntry.coreClient = cc
+	onuDeviceEntry.devState = cmn.DeviceStatusInit
+	onuDeviceEntry.SOnuPersistentData.PersUniConfig = make([]uniPersConfig, 0)
+	onuDeviceEntry.SOnuPersistentData.PersTcontMap = make(map[uint16]uint16)
+	onuDeviceEntry.chReconcilingFlowsFinished = make(chan bool)
+	onuDeviceEntry.reconcilingFlows = false
+	onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
+	onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan cmn.Message, 2048)
+	//openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
+	//OMCI related databases are on a per-agent basis. State machines and tasks
+	//are per ONU Vendor
+	//
+	// MIB Synchronization Database - possible overloading from arguments
+	supportedFsms := onuDeviceEntry.pOpenOnuAc.GetSupportedFsms()
+	if supportedFsms != nil {
+		onuDeviceEntry.supportedFsms = *supportedFsms
+	} else {
+		// This branch is currently not used and is for potential future usage of alternative MIB Sync FSMs only!
+		//var mibSyncFsm = NewMibSynchronizer()
+		// use some internal defaults, if not defined from outside
+		onuDeviceEntry.supportedFsms = cmn.OmciDeviceFsms{
+			"mib-synchronizer": {
+				//mibSyncFsm,        // Implements the MIB synchronization state machine
+				DatabaseClass: onuDeviceEntry.mibDbVolatileDict, // Implements volatile ME MIB database
+				//true,                             // Advertise events on OpenOMCI event bus
+				AuditInterval: dh.GetAlarmAuditInterval(), // 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(ctx, "access2mibDbClass")
+	go onuDeviceEntry.mibDbClass(ctx)
+	if !dh.IsReconciling() {
+		onuDeviceEntry.mibAuditInterval = onuDeviceEntry.supportedFsms["mib-synchronizer"].AuditInterval
+		onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval = onuDeviceEntry.mibAuditInterval
+		onuDeviceEntry.alarmAuditInterval = dh.GetAlarmAuditInterval()
+		onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval = onuDeviceEntry.alarmAuditInterval
+	} else {
+		logger.Debugw(ctx, "reconciling - take audit interval from persistent data", log.Fields{"device-id": onuDeviceEntry.deviceID})
+		// TODO: This is a preparation for VOL-VOL-3811 to preserve config history in case of
+		// vendor- or deviceID-specific configurations via voltctl-commands
+		onuDeviceEntry.mibAuditInterval = onuDeviceEntry.SOnuPersistentData.PersMibAuditInterval
+		onuDeviceEntry.alarmAuditInterval = onuDeviceEntry.SOnuPersistentData.PersAlarmAuditInterval
+	}
+	logger.Debugw(ctx, "MibAuditInterval and AlarmAuditInterval is set to", log.Fields{"mib-audit-interval": onuDeviceEntry.mibAuditInterval,
+		"alarm-audit-interval": onuDeviceEntry.alarmAuditInterval})
+	// TODO: periodical mib resync will be implemented with story VOL-3792
+	//onuDeviceEntry.mibNextDbResync = 0
+
+	// Omci related Mib upload sync state machine
+	mibUploadChan := make(chan cmn.Message, 2048)
+	onuDeviceEntry.PMibUploadFsm = cmn.NewAdapterFsm("MibUpload", onuDeviceEntry.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: UlStUploadDone},
+			{Name: UlEvSuccess, Src: []string{UlStUploading}, Dst: UlStUploadDone},
+
+			{Name: UlEvSuccess, Src: []string{UlStUploadDone}, Dst: UlStInSync},
+			//{Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStInSync},
+			{Name: UlEvSuccess, Src: []string{UlStExaminingMds}, Dst: UlStExaminingMdsSuccess},
+			// TODO: As long as mib-resynchronizing is not implemented, failed MDS-examination triggers
+			// mib-reset and new provisioning at this point
+			//{Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResynchronizing},
+			{Name: UlEvMismatch, Src: []string{UlStExaminingMds}, Dst: UlStResettingMib},
+
+			{Name: UlEvSuccess, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStInSync},
+			{Name: UlEvMismatch, Src: []string{UlStExaminingMdsSuccess}, Dst: UlStResettingMib},
+
+			{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: UlStReAuditing},
+			{Name: UlEvForceResync, Src: []string{UlStAuditing}, Dst: UlStResynchronizing},
+
+			{Name: UlEvSuccess, Src: []string{UlStReAuditing}, Dst: UlStInSync},
+			{Name: UlEvMismatch, Src: []string{UlStReAuditing}, Dst: UlStResettingMib},
+
+			{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,
+				UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStStarting},
+
+			{Name: UlEvStop, Src: []string{UlStStarting, UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipmentID, UlStGettingFirstSwVersion,
+				UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing, UlStExaminingMds,
+				UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStDisabled},
+		},
+
+		fsm.Callbacks{
+			"enter_state":                         func(e *fsm.Event) { onuDeviceEntry.PMibUploadFsm.LogFsmStateChange(ctx, e) },
+			"enter_" + UlStStarting:               func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
+			"enter_" + UlStResettingMib:           func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
+			"enter_" + UlStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
+			"enter_" + UlStGettingEquipmentID:     func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipmentIDState(ctx, e) },
+			"enter_" + UlStGettingFirstSwVersion:  func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
+			"enter_" + UlStGettingSecondSwVersion: func(e *fsm.Event) { onuDeviceEntry.enterGettingSecondSwVersionState(ctx, e) },
+			"enter_" + UlStGettingMacAddress:      func(e *fsm.Event) { onuDeviceEntry.enterGettingMacAddressState(ctx, e) },
+			"enter_" + UlStGettingMibTemplate:     func(e *fsm.Event) { onuDeviceEntry.enterGettingMibTemplateState(ctx, e) },
+			"enter_" + UlStUploading:              func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(ctx, e) },
+			"enter_" + UlStUploadDone:             func(e *fsm.Event) { onuDeviceEntry.enterUploadDoneState(ctx, e) },
+			"enter_" + UlStExaminingMds:           func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(ctx, e) },
+			"enter_" + UlStResynchronizing:        func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(ctx, e) },
+			"enter_" + UlStExaminingMdsSuccess:    func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsSuccessState(ctx, e) },
+			"enter_" + UlStAuditing:               func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(ctx, e) },
+			"enter_" + UlStReAuditing:             func(e *fsm.Event) { onuDeviceEntry.enterReAuditingState(ctx, e) },
+			"enter_" + UlStOutOfSync:              func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(ctx, e) },
+			"enter_" + UlStInSync:                 func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(ctx, e) },
+		},
+	)
+	// Omci related Mib download state machine
+	mibDownloadChan := make(chan cmn.Message, 2048)
+	onuDeviceEntry.PMibDownloadFsm = cmn.NewAdapterFsm("MibDownload", onuDeviceEntry.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(ctx, e) },
+			"enter_" + DlStStarting:     func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(ctx, e) },
+			"enter_" + DlStCreatingGal:  func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(ctx, e) },
+			"enter_" + DlStSettingOnu2g: func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(ctx, e) },
+			"enter_" + DlStBridgeInit:   func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(ctx, e) },
+			"enter_" + DlStDownloaded:   func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(ctx, e) },
+			"enter_" + DlStResetting:    func(e *fsm.Event) { onuDeviceEntry.enterResettingState(ctx, e) },
+		},
+	)
+	if onuDeviceEntry.PMibDownloadFsm == nil || onuDeviceEntry.PMibDownloadFsm.PFsm == nil {
+		logger.Errorw(ctx, "MibDownloadFsm could not be instantiated", log.Fields{"device-id": onuDeviceEntry.deviceID})
+		// TODO some specific error treatment - or waiting for crash ?
+	}
+
+	onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, cBasePathMibTemplateKvStore)
+	if onuDeviceEntry.mibTemplateKVStore == nil {
+		logger.Errorw(ctx, "Can't access mibTemplateKVStore - no backend connection to service",
+			log.Fields{"device-id": onuDeviceEntry.deviceID, "service": cBasePathMibTemplateKvStore})
+	}
+
+	onuDeviceEntry.onuKVStorePath = onuDeviceEntry.deviceID
+	baseKvStorePath := fmt.Sprintf(cBasePathOnuKVStore, dh.GetBackendPathPrefix())
+	onuDeviceEntry.onuKVStore = onuDeviceEntry.baseDeviceHandler.SetBackend(ctx, baseKvStorePath)
+	if onuDeviceEntry.onuKVStore == nil {
+		logger.Errorw(ctx, "Can't access onuKVStore - no backend connection to service",
+			log.Fields{"device-id": onuDeviceEntry.deviceID, "service": baseKvStorePath})
+	}
+
+	// Alarm Synchronization Database
+
+	//self._alarm_db = None
+	//self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
+	return &onuDeviceEntry
+}
+
+//Start starts (logs) the omci agent
+func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
+	logger.Debugw(ctx, "OnuDeviceEntry-starting", log.Fields{"for device-id": oo.deviceID})
+	if oo.PDevOmciCC == nil {
+		oo.PDevOmciCC = cmn.NewOmciCC(ctx, oo.deviceID, oo.baseDeviceHandler, oo, oo.baseDeviceHandler.GetOnuAlarmManager(), oo.coreClient)
+		if oo.PDevOmciCC == nil {
+			logger.Errorw(ctx, "Could not create devOmciCc - abort", log.Fields{"for device-id": oo.deviceID})
+			return fmt.Errorf("could not create devOmciCc %s", oo.deviceID)
+		}
+	}
+	return nil
+}
+
+//Stop stops/resets the omciCC
+func (oo *OnuDeviceEntry) Stop(ctx context.Context, abResetOmciCC bool) error {
+	logger.Debugw(ctx, "OnuDeviceEntry-stopping", log.Fields{"for device-id": oo.deviceID})
+	if abResetOmciCC && (oo.PDevOmciCC != nil) {
+		_ = oo.PDevOmciCC.Stop(ctx)
+	}
+	//to allow for all event notifications again when re-using the device and omciCC
+	oo.devState = cmn.DeviceStatusInit
+	return nil
+}
+
+// Reboot - TODO: add comment
+func (oo *OnuDeviceEntry) Reboot(ctx context.Context) error {
+	logger.Debugw(ctx, "OnuDeviceEntry-rebooting", log.Fields{"for device-id": oo.deviceID})
+	if oo.PDevOmciCC != nil {
+		if err := oo.PDevOmciCC.SendReboot(ctx, oo.baseDeviceHandler.GetOmciTimeout(), true, oo.omciRebootMessageReceivedChannel); err != nil {
+			logger.Errorw(ctx, "onu didn't reboot", log.Fields{"for device-id": oo.deviceID})
+			return err
+		}
+	}
+	return nil
+}
+
+// WaitForRebootResponse - TODO: add comment
+func (oo *OnuDeviceEntry) WaitForRebootResponse(ctx context.Context, responseChannel chan cmn.Message) error {
+	select {
+	case <-time.After(oo.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw(ctx, "reboot timeout", log.Fields{"for device-id": oo.deviceID})
+		return fmt.Errorf("rebootTimeout")
+	case data := <-responseChannel:
+		switch data.Data.(cmn.OmciMessage).OmciMsg.MessageType {
+		case omci.RebootResponseType:
+			{
+				msgLayer := (*data.Data.(cmn.OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
+				if msgLayer == nil {
+					return fmt.Errorf("omci Msg layer could not be detected for RebootResponseType")
+				}
+				msgObj, msgOk := msgLayer.(*omci.RebootResponse)
+				if !msgOk {
+					return fmt.Errorf("omci Msg layer could not be assigned for RebootResponseType %s", oo.deviceID)
+				}
+				logger.Debugw(ctx, "RebootResponse data", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj})
+				if msgObj.Result != me.Success {
+					logger.Errorw(ctx, "Omci RebootResponse result error", log.Fields{"device-id": oo.deviceID, "Error": msgObj.Result})
+					// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+					return fmt.Errorf("omci RebootResponse result error indication %s for device %s",
+						msgObj.Result, oo.deviceID)
+				}
+				return nil
+			}
+		}
+		logger.Warnw(ctx, "Reboot response message type error", log.Fields{"for device-id": oo.deviceID})
+		return fmt.Errorf("unexpected OmciResponse type received %s", oo.deviceID)
+	}
+}
+
+//Relay the InSync message via Handler to Rw core - Status update
+func (oo *OnuDeviceEntry) transferSystemEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
+	logger.Debugw(ctx, "relaying system-event", log.Fields{"Event": devEvent})
+	// decouple the handler transfer from further processing here
+	// TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
+	if devEvent == cmn.MibDatabaseSync {
+		if oo.devState < cmn.MibDatabaseSync { //devState has not been synced yet
+			oo.devState = cmn.MibDatabaseSync
+			go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
+			//TODO!!! device control: next step: start MIB capability verification from here ?!!!
+		} else {
+			logger.Debugw(ctx, "mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
+		}
+	} else if devEvent == cmn.MibDownloadDone {
+		if oo.devState < cmn.MibDownloadDone { //devState has not been synced yet
+			oo.devState = cmn.MibDownloadDone
+			go oo.baseDeviceHandler.DeviceProcStatusUpdate(ctx, devEvent)
+		} else {
+			logger.Debugw(ctx, "mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
+		}
+	} else {
+		logger.Warnw(ctx, "device-event not yet handled", log.Fields{"state": devEvent})
+	}
+}
+
+// RestoreDataFromOnuKvStore - TODO: add comment
+func (oo *OnuDeviceEntry) RestoreDataFromOnuKvStore(ctx context.Context) error {
+	if oo.onuKVStore == nil {
+		logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
+		return fmt.Errorf(fmt.Sprintf("onuKVStore-not-set-abort-%s", oo.deviceID))
+	}
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
+	oo.SOnuPersistentData =
+		onuPersistentData{0, 0, "", "", "", "", "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
+	oo.mutexOnuKVStore.RLock()
+	Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
+	oo.mutexOnuKVStore.RUnlock()
+	if err == nil {
+		if Value != nil {
+			logger.Debugw(ctx, "ONU-data read",
+				log.Fields{"Key": Value.Key, "device-id": oo.deviceID})
+			tmpBytes, _ := kvstore.ToByte(Value.Value)
+
+			if err = json.Unmarshal(tmpBytes, &oo.SOnuPersistentData); err != nil {
+				logger.Errorw(ctx, "unable to unmarshal ONU-data", log.Fields{"error": err, "device-id": oo.deviceID})
+				return fmt.Errorf(fmt.Sprintf("unable-to-unmarshal-ONU-data-%s", oo.deviceID))
+			}
+			logger.Debugw(ctx, "ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
+				"device-id": oo.deviceID})
+		} else {
+			logger.Debugw(ctx, "no ONU-data found", log.Fields{"path": oo.onuKVStorePath, "device-id": oo.deviceID})
+			return fmt.Errorf("no-ONU-data-found")
+		}
+	} else {
+		logger.Errorw(ctx, "unable to read from KVstore", log.Fields{"device-id": oo.deviceID})
+		return fmt.Errorf(fmt.Sprintf("unable-to-read-from-KVstore-%s", oo.deviceID))
+	}
+	return nil
+}
+
+// DeleteDataFromOnuKvStore - TODO: add comment
+func (oo *OnuDeviceEntry) DeleteDataFromOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
+	defer wg.Done()
+
+	if oo.onuKVStore == nil {
+		logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
+		oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: onuKVStore not set"))
+		return
+	}
+	var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
+	go oo.deletePersistentData(ctx, processingStep)
+	if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
+		//timeout or error detected
+		logger.Debugw(ctx, "ONU-data not deleted - abort", log.Fields{"device-id": oo.deviceID})
+		oo.setKvProcessingErrorIndication(errors.New("onu-data delete aborted: during kv-access"))
+		return
+	}
+}
+
+func (oo *OnuDeviceEntry) deletePersistentData(ctx context.Context, aProcessingStep uint8) {
+
+	logger.Debugw(ctx, "delete and clear internal persistency data", log.Fields{"device-id": oo.deviceID})
+
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
+
+	oo.SOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector default entry
+	oo.SOnuPersistentData =
+		onuPersistentData{0, 0, "", "", "", "", "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
+	logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
+	oo.mutexOnuKVStore.Lock()
+	err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)
+	oo.mutexOnuKVStore.Unlock()
+	if err != nil {
+		logger.Errorw(ctx, "unable to delete in KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
+		oo.chOnuKvProcessingStep <- 0 //error indication
+		return
+	}
+	oo.chOnuKvProcessingStep <- aProcessingStep //done
+}
+
+// UpdateOnuKvStore - TODO: add comment
+func (oo *OnuDeviceEntry) UpdateOnuKvStore(ctx context.Context, wg *sync.WaitGroup) {
+	defer wg.Done()
+
+	if oo.onuKVStore == nil {
+		logger.Debugw(ctx, "onuKVStore not set - abort", log.Fields{"device-id": oo.deviceID})
+		oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: onuKVStore not set"))
+		return
+	}
+	var processingStep uint8 = 1 // used to synchronize the different processing steps with chOnuKvProcessingStep
+	go oo.storeDataInOnuKvStore(ctx, processingStep)
+	if !oo.waitForTimeoutOrCompletion(ctx, oo.chOnuKvProcessingStep, processingStep) {
+		//timeout or error detected
+		logger.Debugw(ctx, "ONU-data not written - abort", log.Fields{"device-id": oo.deviceID})
+		oo.setKvProcessingErrorIndication(errors.New("onu-data update aborted: during writing process"))
+		return
+	}
+}
+
+func (oo *OnuDeviceEntry) storeDataInOnuKvStore(ctx context.Context, aProcessingStep uint8) {
+
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
+	//assign values which are not already present when NewOnuDeviceEntry() is called
+	onuIndication := oo.baseDeviceHandler.GetOnuIndication()
+	oo.SOnuPersistentData.PersOnuID = onuIndication.OnuId
+	oo.SOnuPersistentData.PersIntfID = onuIndication.IntfId
+	//TODO: verify usage of these values during restart UC
+	oo.SOnuPersistentData.PersAdminState = onuIndication.AdminState
+	oo.SOnuPersistentData.PersOperState = onuIndication.OperState
+
+	logger.Debugw(ctx, "Update ONU-data in KVStore", log.Fields{"device-id": oo.deviceID, "SOnuPersistentData": oo.SOnuPersistentData})
+
+	Value, err := json.Marshal(oo.SOnuPersistentData)
+	if err != nil {
+		logger.Errorw(ctx, "unable to marshal ONU-data", log.Fields{"SOnuPersistentData": oo.SOnuPersistentData,
+			"device-id": oo.deviceID, "err": err})
+		oo.chOnuKvProcessingStep <- 0 //error indication
+		return
+	}
+	oo.pOpenOnuAc.RLockMutexDeviceHandlersMap()
+	if _, exist := oo.pOpenOnuAc.GetDeviceHandler(oo.deviceID); !exist {
+		logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
+		oo.chOnuKvProcessingStep <- aProcessingStep
+		oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
+		return
+	}
+	oo.baseDeviceHandler.RLockMutexDeletionInProgressFlag()
+	if oo.baseDeviceHandler.GetDeletionInProgress() {
+		logger.Debugw(ctx, "delete_device in progress - skip write request", log.Fields{"device-id": oo.deviceID})
+		oo.chOnuKvProcessingStep <- aProcessingStep
+		oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
+		oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
+		return
+	}
+	oo.pOpenOnuAc.RUnlockMutexDeviceHandlersMap()
+	oo.baseDeviceHandler.RUnlockMutexDeletionInProgressFlag()
+
+	oo.mutexOnuKVStore.Lock()
+	err = oo.onuKVStore.Put(ctx, oo.onuKVStorePath, Value)
+	oo.mutexOnuKVStore.Unlock()
+	if err != nil {
+		logger.Errorw(ctx, "unable to write ONU-data into KVstore", log.Fields{"device-id": oo.deviceID, "err": err})
+		oo.chOnuKvProcessingStep <- 0 //error indication
+		return
+	}
+	oo.chOnuKvProcessingStep <- aProcessingStep //done
+}
+
+// UpdateOnuUniTpPath - TODO: add comment
+func (oo *OnuDeviceEntry) UpdateOnuUniTpPath(ctx context.Context, aUniID uint8, aTpID uint8, 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
+	*/
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
+
+	for k, v := range oo.SOnuPersistentData.PersUniConfig {
+		if v.PersUniID == aUniID {
+			existingPath, ok := oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID]
+			logger.Debugw(ctx, "PersUniConfig-entry exists", log.Fields{"device-id": oo.deviceID, "uniID": aUniID,
+				"tpID": aTpID, "path": aPathString, "existingPath": existingPath, "ok": ok})
+			if !ok {
+				logger.Debugw(ctx, "tp-does-not-exist", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "tpID": aTpID, "path": aPathString})
+			}
+			if existingPath != aPathString {
+				if aPathString == "" {
+					//existing entry to be deleted
+					logger.Debugw(ctx, "UniTp delete path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
+					oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = ""
+				} else {
+					//existing entry to be modified
+					logger.Debugw(ctx, "UniTp modify path value", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
+					oo.SOnuPersistentData.PersUniConfig[k].PersTpPathMap[aTpID] = aPathString
+				}
+				return true
+			}
+			//entry already exists
+			if aPathString == "" {
+				//no active TechProfile
+				logger.Debugw(ctx, "UniTp path has already been removed - no AniSide config to be removed", log.Fields{
+					"device-id": oo.deviceID, "uniID": aUniID})
+			} else {
+				//the given TechProfile already exists and is assumed to be active - update devReason as if the config has been done here
+				//was needed e.g. in voltha POD Tests:Validate authentication on a disabled ONU
+				//  (as here the TechProfile has not been removed with the disable-device before the new enable-device)
+				logger.Debugw(ctx, "UniTp path already exists - TechProfile supposed to be active", log.Fields{
+					"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
+				//no deviceReason update (DeviceProcStatusUpdate) here to ensure 'omci_flows_pushed' state within disable/enable procedure of ATT scenario
+				//  (during which the flows are removed/re-assigned but the techProf is left active)
+				//and as the TechProfile is regarded as active we have to verify, if some flow configuration still waits on it
+				//  (should not be the case, but should not harm or be more robust ...)
+				// and to be sure, that for some reason the corresponding TpDelete was lost somewhere in history
+				//  we also reset a possibly outstanding delete request - repeated TpConfig is regarded as valid for waiting flow config
+				if oo.pOnuTP != nil {
+					oo.pOnuTP.SetProfileToDelete(aUniID, aTpID, false)
+				}
+				go oo.baseDeviceHandler.VerifyVlanConfigRequest(ctx, aUniID, aTpID)
+			}
+			return false //indicate 'no change' - nothing more to do, TechProf inter-adapter message is return with success anyway here
+		}
+	}
+	//no entry exists for uniId
+
+	if aPathString == "" {
+		//delete request in non-existing state , accept as no change
+		logger.Debugw(ctx, "UniTp path already removed", log.Fields{"device-id": oo.deviceID, "uniID": aUniID})
+		return false
+	}
+	//new entry to be created
+	logger.Debugw(ctx, "New UniTp path set", log.Fields{"device-id": oo.deviceID, "uniID": aUniID, "path": aPathString})
+	perSubTpPathMap := make(map[uint8]string)
+	perSubTpPathMap[aTpID] = aPathString
+	oo.SOnuPersistentData.PersUniConfig =
+		append(oo.SOnuPersistentData.PersUniConfig, uniPersConfig{PersUniID: aUniID, PersTpPathMap: perSubTpPathMap, PersFlowParams: make([]cmn.UniVlanFlowParams, 0)})
+	return true
+}
+
+// UpdateOnuUniFlowConfig - TODO: add comment
+func (oo *OnuDeviceEntry) UpdateOnuUniFlowConfig(aUniID uint8, aUniVlanFlowParams *[]cmn.UniVlanFlowParams) {
+
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
+
+	for k, v := range oo.SOnuPersistentData.PersUniConfig {
+		if v.PersUniID == aUniID {
+			oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams = make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))
+			copy(oo.SOnuPersistentData.PersUniConfig[k].PersFlowParams, *aUniVlanFlowParams)
+			return
+		}
+	}
+	//flow update was faster than tp-config - create PersUniConfig-entry
+	//TODO!!: following activity to 'add' some new uni entry might not be quite correct if this function is called to clear the data
+	//  (e.g after flow removal from RemoveUniFlowParams()).
+	//  This has the effect of misleading indication that there is still some active UNI entry, even though there might be only some nil flow entry
+	//  The effect of this flaw is that at TechProfile removal there is an additional attempt to remove the entry even though no techProfile exists anymore
+	//  The code is not changed here because of the current release lane, changes might have unexpected secondary effects, perhaps later with more elaborate tests
+	tmpConfig := uniPersConfig{PersUniID: aUniID, PersTpPathMap: make(map[uint8]string), PersFlowParams: make([]cmn.UniVlanFlowParams, len(*aUniVlanFlowParams))}
+	copy(tmpConfig.PersFlowParams, *aUniVlanFlowParams)
+	oo.SOnuPersistentData.PersUniConfig = append(oo.SOnuPersistentData.PersUniConfig, tmpConfig)
+}
+
+func (oo *OnuDeviceEntry) waitForTimeoutOrCompletion(
+	ctx context.Context, aChOnuProcessingStep <-chan uint8, aProcessingStep uint8) bool {
+	select {
+	case <-ctx.Done():
+		logger.Warnw(ctx, "processing not completed in-time!",
+			log.Fields{"device-id": oo.deviceID, "error": ctx.Err()})
+		return false
+	case rxStep := <-aChOnuProcessingStep:
+		if rxStep == aProcessingStep {
+			return true
+		}
+		//all other values are not accepted - including 0 for error indication
+		logger.Warnw(ctx, "Invalid processing step received: abort!",
+			log.Fields{"device-id": oo.deviceID,
+				"wantedStep": aProcessingStep, "haveStep": rxStep})
+		return false
+	}
+}
+
+// ResetKvProcessingErrorIndication - TODO: add comment
+func (oo *OnuDeviceEntry) ResetKvProcessingErrorIndication() {
+	oo.mutexOnuKVStoreProcResult.Lock()
+	oo.onuKVStoreProcResult = nil
+	oo.mutexOnuKVStoreProcResult.Unlock()
+}
+
+// GetKvProcessingErrorIndication - TODO: add comment
+func (oo *OnuDeviceEntry) GetKvProcessingErrorIndication() error {
+	oo.mutexOnuKVStoreProcResult.RLock()
+	value := oo.onuKVStoreProcResult
+	oo.mutexOnuKVStoreProcResult.RUnlock()
+	return value
+}
+
+func (oo *OnuDeviceEntry) setKvProcessingErrorIndication(value error) {
+	oo.mutexOnuKVStoreProcResult.Lock()
+	oo.onuKVStoreProcResult = value
+	oo.mutexOnuKVStoreProcResult.Unlock()
+}
+
+// IncrementMibDataSync - TODO: add comment
+func (oo *OnuDeviceEntry) IncrementMibDataSync(ctx context.Context) {
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
+	if oo.SOnuPersistentData.PersMibDataSyncAdpt < 255 {
+		oo.SOnuPersistentData.PersMibDataSyncAdpt++
+	} else {
+		// per G.984 and G.988 overflow starts over at 1 given 0 is reserved for reset
+		oo.SOnuPersistentData.PersMibDataSyncAdpt = 1
+	}
+	logger.Debugf(ctx, "mibDataSync updated - mds: %d - device-id: %s", oo.SOnuPersistentData.PersMibDataSyncAdpt, oo.deviceID)
+}
+
+// ModifySwImageInactiveVersion - updates the inactive SW image version stored
+func (oo *OnuDeviceEntry) ModifySwImageInactiveVersion(ctx context.Context, aImageVersion string) {
+	oo.mutexOnuSwImageIndications.Lock()
+	defer oo.mutexOnuSwImageIndications.Unlock()
+	logger.Debugw(ctx, "software-image set inactive version", log.Fields{
+		"device-id": oo.deviceID, "version": aImageVersion})
+	oo.onuSwImageIndications.InActiveEntityEntry.Version = aImageVersion
+	//inactive SW version is not part of persistency data (yet) - no need to update that
+}
+
+// ModifySwImageActiveCommit - updates the active SW commit flag stored
+func (oo *OnuDeviceEntry) ModifySwImageActiveCommit(ctx context.Context, aCommitted uint8) {
+	oo.mutexOnuSwImageIndications.Lock()
+	defer oo.mutexOnuSwImageIndications.Unlock()
+	logger.Debugw(ctx, "software-image set active entity commit flag", log.Fields{
+		"device-id": oo.deviceID, "committed": aCommitted})
+	oo.onuSwImageIndications.ActiveEntityEntry.IsCommitted = aCommitted
+	//commit flag is not part of persistency data (yet) - no need to update that
+}
+
+// GetActiveImageVersion - returns the active SW image version stored
+func (oo *OnuDeviceEntry) GetActiveImageVersion(ctx context.Context) string {
+	oo.mutexOnuSwImageIndications.RLock()
+	if oo.onuSwImageIndications.ActiveEntityEntry.Valid {
+		value := oo.onuSwImageIndications.ActiveEntityEntry.Version
+		oo.mutexOnuSwImageIndications.RUnlock()
+		return value
+	}
+	oo.mutexOnuSwImageIndications.RUnlock()
+	logger.Debugw(ctx, "Active Image is not valid", log.Fields{"device-id": oo.deviceID})
+	return ""
+}
+
+// GetInactiveImageVersion - TODO: add comment
+func (oo *OnuDeviceEntry) GetInactiveImageVersion(ctx context.Context) string {
+	oo.mutexOnuSwImageIndications.RLock()
+	if oo.onuSwImageIndications.InActiveEntityEntry.Valid {
+		value := oo.onuSwImageIndications.InActiveEntityEntry.Version
+		oo.mutexOnuSwImageIndications.RUnlock()
+		return value
+	}
+	oo.mutexOnuSwImageIndications.RUnlock()
+	logger.Debugw(ctx, "Inactive Image is not valid", log.Fields{"device-id": oo.deviceID})
+	return ""
+}
+
+func (oo *OnuDeviceEntry) buildMibTemplatePath() string {
+	oo.MutexPersOnuConfig.RLock()
+	defer oo.MutexPersOnuConfig.RUnlock()
+	return fmt.Sprintf(cSuffixMibTemplateKvStore, oo.SOnuPersistentData.PersVendorID, oo.SOnuPersistentData.PersEquipmentID, oo.SOnuPersistentData.PersActiveSwVersion)
+}
+
+// AllocateFreeTcont - TODO: add comment
+func (oo *OnuDeviceEntry) AllocateFreeTcont(ctx context.Context, allocID uint16) (uint16, bool, error) {
+	logger.Debugw(ctx, "allocate-free-tcont", log.Fields{"device-id": oo.deviceID, "allocID": allocID,
+		"allocated-instances": oo.SOnuPersistentData.PersTcontMap})
+
+	oo.mutexTcontMap.Lock()
+	defer oo.mutexTcontMap.Unlock()
+	if entityID, ok := oo.SOnuPersistentData.PersTcontMap[allocID]; ok {
+		//tcont already allocated before, return the used instance-id
+		return entityID, true, nil
+	}
+	//First allocation of tcont. Find a free instance
+	if tcontInstKeys := oo.pOnuDB.GetSortedInstKeys(ctx, me.TContClassID); len(tcontInstKeys) > 0 {
+		logger.Debugw(ctx, "allocate-free-tcont-db-keys", log.Fields{"device-id": oo.deviceID, "keys": tcontInstKeys})
+		for _, instID := range tcontInstKeys {
+			instExist := false
+			//If this instance exist in map, it means it is not  empty. It is allocated before
+			for _, v := range oo.SOnuPersistentData.PersTcontMap {
+				if v == instID {
+					instExist = true
+					break
+				}
+			}
+			if !instExist {
+				oo.SOnuPersistentData.PersTcontMap[allocID] = instID
+				return instID, false, nil
+			}
+		}
+	}
+	return 0, false, fmt.Errorf(fmt.Sprintf("no-free-tcont-left-for-device-%s", oo.deviceID))
+
+}
+
+// FreeTcont - TODO: add comment
+func (oo *OnuDeviceEntry) FreeTcont(ctx context.Context, allocID uint16) {
+	logger.Debugw(ctx, "free-tcont", log.Fields{"device-id": oo.deviceID, "alloc": allocID})
+	oo.mutexTcontMap.Lock()
+	defer oo.mutexTcontMap.Unlock()
+	delete(oo.SOnuPersistentData.PersTcontMap, allocID)
+}
+
+// GetDevOmciCC - TODO: add comment
+func (oo *OnuDeviceEntry) GetDevOmciCC() *cmn.OmciCC {
+	return oo.PDevOmciCC
+}
+
+// GetOnuDB - TODO: add comment
+func (oo *OnuDeviceEntry) GetOnuDB() *devdb.OnuDeviceDB {
+	return oo.pOnuDB
+}
+
+// GetPersSerialNumber - TODO: add comment
+func (oo *OnuDeviceEntry) GetPersSerialNumber() string {
+	value := oo.SOnuPersistentData.PersSerialNumber
+	return value
+}
+
+// GetPersVendorID - TODO: add comment
+func (oo *OnuDeviceEntry) GetPersVendorID() string {
+	value := oo.SOnuPersistentData.PersVendorID
+	return value
+}
+
+// GetPersEquipmentID - TODO: add comment
+func (oo *OnuDeviceEntry) GetPersEquipmentID() string {
+	value := oo.SOnuPersistentData.PersEquipmentID
+	return value
+}
+
+// GetMibUploadFsmCommChan - TODO: add comment
+func (oo *OnuDeviceEntry) GetMibUploadFsmCommChan() chan cmn.Message {
+	return oo.PMibUploadFsm.CommChan
+}
+
+// GetMibDownloadFsmCommChan - TODO: add comment
+func (oo *OnuDeviceEntry) GetMibDownloadFsmCommChan() chan cmn.Message {
+	return oo.PMibDownloadFsm.CommChan
+}
+
+// GetOmciRebootMsgRevChan - TODO: add comment
+func (oo *OnuDeviceEntry) GetOmciRebootMsgRevChan() chan cmn.Message {
+	return oo.omciRebootMessageReceivedChannel
+}
+
+// LockMutexOnuSwImageIndications - TODO: add comment
+func (oo *OnuDeviceEntry) LockMutexOnuSwImageIndications() {
+	oo.mutexOnuSwImageIndications.Lock()
+}
+
+// UnlockMutexOnuSwImageIndications - TODO: add comment
+func (oo *OnuDeviceEntry) UnlockMutexOnuSwImageIndications() {
+	oo.mutexOnuSwImageIndications.Unlock()
+}
+
+// GetOnuSwImageIndications - TODO: add comment
+func (oo *OnuDeviceEntry) GetOnuSwImageIndications() cmn.SswImageIndications {
+	return oo.onuSwImageIndications
+}
+
+// SetOnuSwImageIndications - TODO: add comment
+func (oo *OnuDeviceEntry) SetOnuSwImageIndications(value cmn.SswImageIndications) {
+	oo.onuSwImageIndications = value
+}
+
+// LockMutexPersOnuConfig - TODO: add comment
+func (oo *OnuDeviceEntry) LockMutexPersOnuConfig() {
+	oo.MutexPersOnuConfig.Lock()
+}
+
+// UnlockMutexPersOnuConfig - TODO: add comment
+func (oo *OnuDeviceEntry) UnlockMutexPersOnuConfig() {
+	oo.MutexPersOnuConfig.Unlock()
+}
+
+// GetPersActiveSwVersion - TODO: add comment
+func (oo *OnuDeviceEntry) GetPersActiveSwVersion() string {
+	return oo.SOnuPersistentData.PersActiveSwVersion
+}
+
+// SetPersActiveSwVersion - TODO: add comment
+func (oo *OnuDeviceEntry) SetPersActiveSwVersion(value string) {
+	oo.SOnuPersistentData.PersActiveSwVersion = value
+}
+
+// SetReconcilingFlows - TODO: add comment
+func (oo *OnuDeviceEntry) SetReconcilingFlows(value bool) {
+	oo.mutexReconcilingFlowsFlag.Lock()
+	oo.reconcilingFlows = value
+	oo.mutexReconcilingFlowsFlag.Unlock()
+}
+
+// SetChReconcilingFlowsFinished - TODO: add comment
+func (oo *OnuDeviceEntry) SetChReconcilingFlowsFinished(value bool) {
+	oo.chReconcilingFlowsFinished <- value
+}
+
+// IsReconcilingFlows - TODO: add comment
+func (oo *OnuDeviceEntry) IsReconcilingFlows() bool {
+	oo.mutexReconcilingFlowsFlag.RLock()
+	value := oo.reconcilingFlows
+	oo.mutexReconcilingFlowsFlag.RUnlock()
+	return value
+}