[VOL-3038] Configuration of tech profiles 1t1gem
version: 0.1.11-dev124

Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: Iae456e0eb057c885e5d094a3dbb13c8ab7284537
diff --git a/VERSION b/VERSION
index 4948bd9..0ddab70 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.11-dev123
+0.1.11-dev124
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index bbd7660..f27e3da 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -291,15 +291,18 @@
 				//TODO!!! Generally: In this scheme it would be good to have some means to indicate
 				//  possible problems to the caller later autonomously
 
-				// some code to coordinate TP 'run to completion'
-				// attention: completion and wg.Add is assumed to be done in both routines,
-				// no timeout control so far (needed)
+				// 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)
+
 				var wg sync.WaitGroup
 				wg.Add(2) // for the 2 go routines to finish
-				go dh.pOnuTP.configureUniTp(techProfMsg.UniId, techProfMsg.Path, &wg)
-				go dh.pOnuTP.updateOnuTpPathKvStore(&wg)
+				// attention: deadline completion check and wg.Done is to be done in both routines
+				go dh.pOnuTP.configureUniTp(dctx, techProfMsg.UniId, techProfMsg.Path, &wg)
+				go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
 				//the wait.. function is responsible for tpProcMutex.Unlock()
-				go dh.pOnuTP.waitForTpCompletion(&wg) //let that also run off-line to let the IA messaging return!
+				go dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
 			} else {
 				dh.pOnuTP.unlockTpProcMutex()
 			}
@@ -323,12 +326,17 @@
 
 			//compare TECH_PROFILE_DOWNLOAD_REQUEST
 			dh.pOnuTP.lockTpProcMutex()
+
+			// 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)
+
 			var wg sync.WaitGroup
 			wg.Add(1) // for the 1 go routine to finish
-			go dh.pOnuTP.deleteTpRessource(delGemPortMsg.UniId, delGemPortMsg.TpPath,
+			go dh.pOnuTP.deleteTpResource(dctx, delGemPortMsg.UniId, delGemPortMsg.TpPath,
 				cResourceGemPort, delGemPortMsg.GemPortId, &wg)
 			//the wait.. function is responsible for tpProcMutex.Unlock()
-			go dh.pOnuTP.waitForTpCompletion(&wg) //let that also run off-line to let the IA messaging return!
+			go dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
 		}
 	case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
 		{
@@ -350,14 +358,18 @@
 			//compare TECH_PROFILE_DOWNLOAD_REQUEST
 			dh.pOnuTP.lockTpProcMutex()
 			if bTpModify := dh.pOnuTP.updateOnuUniTpPath(delTcontMsg.UniId, ""); bTpModify == true {
+				// 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)
+
 				var wg sync.WaitGroup
-				wg.Add(2) // for the 1 go routine to finish
-				go dh.pOnuTP.deleteTpRessource(delTcontMsg.UniId, delTcontMsg.TpPath,
+				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(&wg)
+				go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
 				//the wait.. function is responsible for tpProcMutex.Unlock()
-				go dh.pOnuTP.waitForTpCompletion(&wg) //let that also run off-line to let the IA messaging return!
+				go dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
 			} else {
 				dh.pOnuTP.unlockTpProcMutex()
 			}
@@ -918,13 +930,19 @@
 				}
 			}
 		default:
-			{ //port lock/unlock FSM's may be active
+			{
+				//port lock/unlock FSM's may be active
 				if dh.pUnlockStateFsm != nil {
 					dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event("reset")
 				}
 				if dh.pLockStateFsm != nil {
 					dh.pLockStateFsm.pAdaptFsm.pFsm.Event("reset")
 				}
+				//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("reset")
+				}
 			}
 			//TODO!!! care about PM/Alarm processing once started
 		}
@@ -974,12 +992,15 @@
 	switch dev_Event {
 	case MibDatabaseSync:
 		{
-			logger.Infow("MibInSync event: update dev state to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
+			logger.Debugw("MibInSync event received", log.Fields{"deviceID": dh.deviceID})
 			//initiate DevStateUpdate
 			if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
 				logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
 					"deviceID": dh.deviceID, "error": err})
+			} else {
+				logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
 			}
+			//set internal state anyway - as it was done
 			dh.deviceReason = "discovery-mibsync-complete"
 
 			pDevEntry := dh.GetOnuDeviceEntry(false)
@@ -1059,20 +1080,23 @@
 		}
 	case MibDownloadDone:
 		{
-			logger.Infow("MibDownloadDone event: update dev state to 'Oper.Active'", log.Fields{"deviceID": dh.deviceID})
+			logger.Debugw("MibDownloadDone event received", log.Fields{"deviceID": dh.deviceID})
 			//initiate DevStateUpdate
 			if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
 				voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
 				logger.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.deviceID, "error": err})
+			} else {
+				logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"deviceID": dh.deviceID})
 			}
 
-			logger.Debug("MibDownloadDone Event: update dev reason to 'initial-mib-downloaded'")
 			if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
 				logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
 					log.Fields{"deviceID": dh.deviceID, "error": err})
+			} else {
+				logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"deviceID": dh.deviceID})
 			}
+			//set internal state anyway - as it was done
 			dh.deviceReason = "initial-mib-downloaded"
-
 			// *** should generate UniUnlockStateDone event *****
 			if dh.pUnlockStateFsm == nil {
 				dh.createUniLockFsm(false, UniUnlockStateDone)
@@ -1089,6 +1113,26 @@
 			raisedTs := time.Now().UnixNano()
 			go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
 		}
+	case OmciAniConfigDone:
+		{
+			logger.Debugw("OmciAniConfigDone event received", log.Fields{"deviceID": dh.deviceID})
+			//TODO!: it might be needed to check some 'cached' pending flow configuration (vlan setting)
+			//  - to consider with outstanding flow implementation
+			// attention: the device reason update is done based on ONU-UNI-Port related activity
+			//  - which may cause some inconsistency
+			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 err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
+					logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
+						log.Fields{"deviceID": dh.deviceID, "error": err})
+				} else {
+					logger.Infow("update dev reason to 'tech-profile-config-download-success'",
+						log.Fields{"deviceID": dh.deviceID})
+				}
+				//set internal state anyway - as it was done
+				dh.deviceReason = "tech-profile-config-download-success"
+			}
+		}
 	default:
 		{
 			logger.Warnw("unhandled-device-event", log.Fields{"deviceID": dh.deviceID, "event": dev_Event})
diff --git a/internal/pkg/onuadaptercore/omci_ani_config.go b/internal/pkg/onuadaptercore/omci_ani_config.go
new file mode 100644
index 0000000..d968edb
--- /dev/null
+++ b/internal/pkg/onuadaptercore/omci_ani_config.go
@@ -0,0 +1,604 @@
+/*
+ * 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"
+	"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"
+	//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"
+)
+
+//UniPonAniConfigFsm defines the structure for the state machine to lock/unlock the ONU UNI ports via OMCI
+type UniPonAniConfigFsm struct {
+	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
+	chSuccess                chan<- uint8
+	procStep                 uint8
+	chanSet                  bool
+	mapperSP0ID              uint16
+	macBPCD0ID               uint16
+	tcont0ID                 uint16
+	alloc0ID                 uint16
+	gemPortXID               []uint16
+	upQueueXID               []uint16
+	downQueueXID             []uint16
+}
+
+//NewUniPonAniConfigFsm is the 'constructor' for the state machine to lock/unlock the 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,
+		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(
+		"disabled",
+		fsm.Events{
+
+			{Name: "start", Src: []string{"disabled"}, Dst: "starting"},
+
+			//Note: .1p-Mapper and MBPCD might also have multi instances (per T-Cont) - by now only one 1 T-Cont considered!
+			{Name: "start_config", Src: []string{"starting"}, Dst: "creatingDot1PMapper"},
+			{Name: "rx_dot1pmap_cresp", Src: []string{"creatingDot1PMapper"}, Dst: "creatingMBPCD"},
+			{Name: "rx_mbpcd_resp", Src: []string{"creatingMBPCD"}, Dst: "settingTconts"},
+			{Name: "rx_tconts_resp", Src: []string{"settingTconts"}, Dst: "creatingGemNCTPs"},
+			// the creatingGemNCTPs state is used for multi ME config if required for all configured/available GemPorts
+			{Name: "rx_gemntcps_resp", Src: []string{"creatingGemNCTPs"}, Dst: "creatingGemIWs"},
+			// the creatingGemIWs state is used for multi ME config if required for all configured/available GemPorts
+			{Name: "rx_gemiws_resp", Src: []string{"creatingGemIWs"}, Dst: "settingPQs"},
+			// the settingPQs state is used for multi ME config if required for all configured/available upstream PriorityQueues
+			{Name: "rx_prioqs_resp", Src: []string{"settingPQs"}, Dst: "settingDot1PMapper"},
+			{Name: "rx_dot1pmap_sresp", Src: []string{"settingDot1PMapper"}, Dst: "aniConfigDone"},
+
+			{Name: "timeout_simple", Src: []string{
+				"creatingDot1PMapper", "creatingMBPCD", "settingTconts", "settingDot1PMapper"}, Dst: "starting"},
+			{Name: "timeout_mids", Src: []string{
+				"creatingGemNCTPs", "creatingGemIWs", "settingPQs"}, Dst: "starting"},
+
+			// exceptional treatment for all states except "resetting"
+			{Name: "reset", Src: []string{"starting", "creatingDot1PMapper", "creatingMBPCD",
+				"settingTconts", "creatingGemNCTPs", "creatingGemIWs", "settingPQs", "settingDot1PMapper",
+				"aniConfigDone"}, Dst: "resetting"},
+			// the only way to get to resource-cleared disabled state again is via "resseting"
+			{Name: "restart", Src: []string{"resetting"}, Dst: "disabled"},
+		},
+
+		fsm.Callbacks{
+			"enter_state":               func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(e) },
+			"enter_starting":            func(e *fsm.Event) { instFsm.enterConfigStartingState(e) },
+			"enter_creatingDot1PMapper": func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(e) },
+			"enter_creatingMBPCD":       func(e *fsm.Event) { instFsm.enterCreatingMBPCD(e) },
+			"enter_settingTconts":       func(e *fsm.Event) { instFsm.enterSettingTconts(e) },
+			"enter_creatingGemNCTPs":    func(e *fsm.Event) { instFsm.enterCreatingGemNCTPs(e) },
+			"enter_creatingGemIWs":      func(e *fsm.Event) { instFsm.enterCreatingGemIWs(e) },
+			"enter_settingPQs":          func(e *fsm.Event) { instFsm.enterSettingPQs(e) },
+			"enter_settingDot1PMapper":  func(e *fsm.Event) { instFsm.enterSettingDot1PMapper(e) },
+			"enter_aniConfigDone":       func(e *fsm.Event) { instFsm.enterAniConfigDone(e) },
+			"enter_resetting":           func(e *fsm.Event) { instFsm.enterResettingState(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) enterConfigStartingState(e *fsm.Event) {
+	logger.Debugw("UniPonAniConfigFsm start", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.pAdaptFsm.deviceID})
+	// in case the used channel is not yet defined (can be re-used after restarts)
+	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
+		}
+	}
+	// start go routine for processing of LockState messages
+	go oFsm.ProcessOmciAniMessages()
+
+	//let the state machine run forward from here directly
+	pConfigAniStateAFsm := oFsm.pAdaptFsm
+	if pConfigAniStateAFsm != 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
+				//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
+				oFsm.tcont0ID = 0x8001 //TODO!: for now fixed, but target is to use value from MibUpload (mibDB)
+				oFsm.alloc0ID = (*(oFsm.pUniTechProf.mapPonAniConfig[uint32(oFsm.pOnuUniPort.uniId)]))[0].tcontParams.allocID
+				//TODO!! this is just for the first GemPort right now - needs update
+				oFsm.gemPortXID = append(oFsm.gemPortXID,
+					(*(oFsm.pUniTechProf.mapPonAniConfig[uint32(oFsm.pOnuUniPort.uniId)]))[0].mapGemPortParams[0].gemPortID)
+				oFsm.upQueueXID = append(oFsm.upQueueXID, 0x8001) //TODO!: for now fixed, but target is to use value from MibUpload (mibDB)
+				//TODO!: for now fixed, but target is to use value from MibUpload (mibDB), also TechProf setting dependency may exist!
+				oFsm.downQueueXID = append(oFsm.downQueueXID, 1)
+
+				a_pAFsm.pFsm.Event("start_config")
+			}
+		}(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)
+	//accept also nil as (error) return value for writing to LastTx
+	//  - this avoids misinterpretation of new received OMCI messages
+	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)
+	//accept also nil as (error) return value for writing to LastTx
+	//  - this avoids misinterpretation of new received OMCI messages
+	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)
+	//accept also nil as (error) return value for writing to LastTx
+	//  - this avoids misinterpretation of new received OMCI messages
+	oFsm.pOmciCC.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *UniPonAniConfigFsm) enterCreatingGemNCTPs(e *fsm.Event) {
+	//TODO!! this is just for the first GemPort right now - needs update
+	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})
+
+	//TODO!! in MultiGemPort constellation the IwTpPtr setting will get variable -f(Prio) based on pUniTechProf
+	logger.Debugw("UniPonAniConfigFsm Tx Set::1pMapper SingleGem", log.Fields{
+		"EntitytId":  strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
+		"GemIwTpPtr": strconv.FormatInt(int64(oFsm.gemPortXID[0]), 16),
+		"in state":   e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
+	meParams := me.ParamData{
+		EntityID: oFsm.mapperSP0ID,
+		Attributes: me.AttributeValueMap{
+			"InterworkTpPointerForPBitPriority0": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority1": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority2": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority3": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority4": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority5": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority6": oFsm.gemPortXID[0],
+			"InterworkTpPointerForPBitPriority7": oFsm.gemPortXID[0],
+		},
+	}
+	meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(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
+}
+
+func (oFsm *UniPonAniConfigFsm) enterAniConfigDone(e *fsm.Event) {
+
+	//mirror the chanSet state as it will be reset by FSM reset
+	loChanSet := oFsm.chanSet
+
+	//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(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				a_pAFsm.pFsm.Event("reset")
+			}
+		}(pConfigAniStateAFsm)
+	}
+
+	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)
+
+	if loChanSet {
+		// 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
+	}
+}
+
+func (oFsm *UniPonAniConfigFsm) enterResettingState(e *fsm.Event) {
+	logger.Debugw("UniPonAniConfigFsm resetting", log.Fields{"device-id": oFsm.pAdaptFsm.deviceID})
+	oFsm.chanSet = false //reset the internal channel state
+	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(a_pAFsm *AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.pFsm != nil {
+				a_pAFsm.pFsm.Event("restart")
+			}
+		}(pConfigAniStateAFsm)
+	}
+}
+
+func (oFsm *UniPonAniConfigFsm) ProcessOmciAniMessages( /*ctx context.Context*/ ) {
+	logger.Debugw("Start UniPonAniConfigFsm Msg processing", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+loop:
+	for {
+		select {
+		// case <-ctx.Done():
+		// 	logger.Info("MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.pAdaptFsm.deviceID})
+		// 	break loop
+		case 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("reset")
+				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) 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:
+		{
+			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{"deviceId": 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() {
+				//store the created ME into DB //TODO??? obviously the Python code does not store the config ...
+				// if, then something like:
+				//oFsm.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 oFsm.pOmciCC.pLastTxMeInstance.GetName() {
+				case "Ieee8021PMapperServiceProfile":
+					{ // let the FSM proceed ...
+						oFsm.pAdaptFsm.pFsm.Event("rx_dot1pmap_cresp")
+					}
+				case "MacBridgePortConfigurationData":
+					{ // let the FSM proceed ...
+						oFsm.pAdaptFsm.pFsm.Event("rx_mbpcd_resp")
+					}
+				case "GemPortNetworkCtp", "GemInterworkingTerminationPoint":
+					{ // let aniConfig Multi-Id processing proceed by stopping the wait function
+						oFsm.omciMIdsResponseReceived <- true
+					}
+				}
+			}
+		} //CreateResponseType
+	case omci.SetResponseType:
+		{
+			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{"deviceId": 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("rx_tconts_resp")
+					}
+				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("rx_dot1pmap_sresp")
+					}
+				}
+			}
+		} //SetResponseType
+	default:
+		{
+			logger.Errorw("UniPonAniConfigFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
+			return
+		}
+	}
+}
+
+func (oFsm *UniPonAniConfigFsm) performCreatingGemNCTPs() {
+	//TODO!! this is just for the first GemPort right now - needs update
+	//   .. for gemPort in range gemPortXID
+	logger.Infow("UniPonAniConfigFsm Tx Create::GemNWCtp", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.gemPortXID[0]), 16),
+		"TcontId":   strconv.FormatInt(int64(oFsm.tcont0ID), 16),
+		"device-id": oFsm.pAdaptFsm.deviceID})
+	meParams := me.ParamData{
+		EntityID: oFsm.gemPortXID[0],
+		Attributes: me.AttributeValueMap{
+			"PortId":       oFsm.gemPortXID[0], //same as EntityID
+			"TContPointer": oFsm.tcont0ID,
+			"Direction":    (*(oFsm.pUniTechProf.mapPonAniConfig[uint32(oFsm.pOnuUniPort.uniId)]))[0].mapGemPortParams[0].direction,
+			//ONU-G.TrafficManagementOption dependency ->PrioQueue or TCont
+			//  TODO!! verify dependency and QueueId in case of Multi-GemPort setup!
+			"TrafficManagementPointerForUpstream": oFsm.upQueueXID[0], //might be different in wrr-only Setup - tcont0ID
+			"PriorityQueuePointerForDownStream":   oFsm.downQueueXID[0],
+		},
+	}
+	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{"deviceId": oFsm.pAdaptFsm.deviceID, "GemIndex": 0}) //running index in loop later!
+		oFsm.pAdaptFsm.pFsm.Event("reset")
+		return
+	}
+	//for all GemPortID's ports - later
+
+	// if Config has been done for all GemPort instances let the FSM proceed
+	logger.Debugw("GemNWCtp create loop finished", log.Fields{"deviceId": oFsm.pAdaptFsm.deviceID})
+	oFsm.pAdaptFsm.pFsm.Event("rx_gemntcps_resp")
+	return
+}
+
+func (oFsm *UniPonAniConfigFsm) performCreatingGemIWs() {
+	//TODO!! this is just for the first GemPort right now - needs update
+	//   .. for gemPort in range gemPortXID
+	logger.Infow("UniPonAniConfigFsm Tx Create::GemIwTp", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.gemPortXID[0]), 16),
+		"SPPtr":     strconv.FormatInt(int64(oFsm.mapperSP0ID), 16),
+		"device-id": oFsm.pAdaptFsm.deviceID})
+	meParams := me.ParamData{
+		EntityID: oFsm.gemPortXID[0],
+		Attributes: me.AttributeValueMap{
+			"GemPortNetworkCtpConnectivityPointer": oFsm.gemPortXID[0], //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{"deviceId": oFsm.pAdaptFsm.deviceID, "GemIndex": 0}) //running index in loop later!
+		oFsm.pAdaptFsm.pFsm.Event("reset")
+		return
+	}
+	//for all GemPortID's ports - later
+
+	// if Config has been done for all GemPort instances let the FSM proceed
+	logger.Debugw("GemIwTp create loop finished", log.Fields{"deviceId": oFsm.pAdaptFsm.deviceID})
+	oFsm.pAdaptFsm.pFsm.Event("rx_gemiws_resp")
+	return
+}
+
+func (oFsm *UniPonAniConfigFsm) performSettingPQs() {
+	//TODO!! this is just for the first upstream PrioQueue right now - needs update
+	//TODO!! implementation is restricted to WRR setting on the TrafficScheduler/Tcont
+	//  SP setting would allow relatedPort(Prio) setting in case ONU supports config (ONU-2G QOS)
+
+	//   .. for prioQueu in range upQueueXID
+	weight := (*(oFsm.pUniTechProf.mapPonAniConfig[uint32(oFsm.pOnuUniPort.uniId)]))[0].mapGemPortParams[0].queueWeight
+	logger.Infow("UniPonAniConfigFsm Tx Set::PrioQueue", log.Fields{
+		"EntitytId": strconv.FormatInt(int64(oFsm.upQueueXID[0]), 16),
+		"Weight":    weight,
+		"device-id": oFsm.pAdaptFsm.deviceID})
+	meParams := me.ParamData{
+		EntityID: oFsm.upQueueXID[0],
+		Attributes: me.AttributeValueMap{
+			"Weight": weight,
+		},
+	}
+	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{"deviceId": oFsm.pAdaptFsm.deviceID, "QueueIndex": 0}) //running index in loop later!
+		oFsm.pAdaptFsm.pFsm.Event("reset")
+		return
+	}
+	//for all upstream prioQueus - later
+
+	// if Config has been done for all PrioQueue instances let the FSM proceed
+	logger.Debugw("PrioQueue set loop finished", log.Fields{"deviceId": oFsm.pAdaptFsm.deviceID})
+	oFsm.pAdaptFsm.pFsm.Event("rx_prioqs_resp")
+	return
+}
+
+func (oFsm *UniPonAniConfigFsm) waitforOmciResponse() error {
+	select {
+	// maybe be also some outside cancel (but no context modelled for the moment ...)
+	// case <-ctx.Done():
+	// 		logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
+	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 == true {
+			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
index 7edd20e..1987562 100644
--- a/internal/pkg/onuadaptercore/omci_cc.go
+++ b/internal/pkg/onuadaptercore/omci_cc.go
@@ -221,7 +221,7 @@
 		return errors.New("could not assign omci layer")
 	}
 	logger.Debugw("omci-message-decoded:", log.Fields{"omciMsgType": omciMsg.MessageType,
-		"transCorrId": omciMsg.TransactionID, "DeviceIdent": omciMsg.DeviceIdentifier})
+		"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")
@@ -535,8 +535,8 @@
 //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 received:", log.Fields{"omciMsgType": omciMsg.MessageType,
-		"transCorrId": omciMsg.TransactionID, "deviceId": oo.deviceID})
+	logger.Debugw("omci-message-response - transfer on omciRespChannel", log.Fields{"omciMsgType": omciMsg.MessageType,
+		"transCorrId": strconv.FormatInt(int64(omciMsg.TransactionID), 16), "deviceId": oo.deviceID})
 
 	if oo.pOnuDeviceEntry == nil {
 		logger.Errorw("Abort receiving OMCI response, DeviceEntryPointer is nil", log.Fields{
@@ -631,7 +631,8 @@
 
 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{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
+	logger.Debugw("send GalEnetProfile-Create-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
 
 	meParams := me.ParamData{
 		EntityID:   galEthernetEID,
@@ -663,21 +664,20 @@
 			logger.Errorw("Cannot send GalEnetProfile create", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send GalEnetProfile-Create-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate GalEnetProfileInstance", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": oo.deviceID})
-		return nil
+		logger.Debug("send GalEnetProfile-Create-msg done")
+		return meInstance
 	}
+	logger.Errorw("Cannot generate GalEnetProfileInstance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
+	logger.Debugw("send ONU2-G-Set-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
 
 	// ONU-G ME-ID is defined to be 0, but we could verify, if the ONU really supports the desired
 	//   connectivity mode 5 (in ConnCap)
@@ -712,23 +712,21 @@
 			logger.Errorw("Cannot send ONU2-G set", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send ONU2-G-Set-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate ONU2-G", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": 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(), "deviceId": oo.deviceID})
+	return nil
 }
 
 func (oo *OmciCC) sendCreateMBServiceProfile(ctx context.Context,
 	a_pUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
 	tid := oo.GetNextTid(highPrio)
 	instID := macBridgeServiceProfileEID + uint16(a_pUniPort.macBpNo)
-	logger.Debugw("send MBSP-Create-msg:", log.Fields{
-		"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": instID})
+	logger.Debugw("send MBSP-Create-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
 
 	meParams := me.ParamData{
 		EntityID: instID,
@@ -770,23 +768,21 @@
 			logger.Errorw("Cannot send MBSP create", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send MBSP-Create-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate MBSP Instance", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": oo.deviceID})
-		return nil
+		logger.Debug("send MBSP-Create-msg done")
+		return meInstance
 	}
+	logger.Errorw("Cannot generate MBSP Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": oo.deviceID})
+	return nil
 }
 
 func (oo *OmciCC) sendCreateMBPConfigData(ctx context.Context,
 	a_pUniPort *OnuUniPort, timeout int, highPrio bool) *me.ManagedEntity {
 	tid := oo.GetNextTid(highPrio)
 	instID := macBridgePortAniEID + a_pUniPort.entityId
-	logger.Debugw("send MBPCD-Create-msg:", log.Fields{
-		"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": instID})
+	logger.Debugw("send MBPCD-Create-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
 
 	meParams := me.ParamData{
 		EntityID: instID,
@@ -824,15 +820,13 @@
 			logger.Errorw("Cannot send MBPCD create", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send MBPCD-Create-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": oo.deviceID})
-		return nil
+		logger.Debug("send MBPCD-Create-msg done")
+		return meInstance
 	}
+	logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": oo.deviceID})
+	return nil
 }
 
 func (oo *OmciCC) sendCreateEVTOConfigData(ctx context.Context,
@@ -840,8 +834,8 @@
 	tid := oo.GetNextTid(highPrio)
 	//same entityId is used as for MBSP (see there), but just arbitrary ...
 	instID := macBridgeServiceProfileEID + uint16(a_pUniPort.macBpNo)
-	logger.Debugw("send EVTOCD-Create-msg:", log.Fields{
-		"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16), "InstId": instID})
+	logger.Debugw("send EVTOCD-Create-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16), "InstId": strconv.FormatInt(int64(instID), 16)})
 
 	// compare python adapter code WA VOL-1311: this is not done here!
 	//   (setting TPID values for the create would probably anyway be ignored by the omci lib)
@@ -883,21 +877,20 @@
 			logger.Errorw("Cannot send EVTOCD create", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send EVTOCD-Create-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": oo.deviceID})
-		return nil
+		logger.Debug("send EVTOCD-Create-msg done")
+		return meInstance
 	}
+	logger.Errorw("Cannot generate EVTOCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
+	logger.Debugw("send ONU-G-Set-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
 
 	// ONU-G ME-ID is defined to be 0, no need to perform a DB lookup
 	meParams := me.ParamData{
@@ -929,21 +922,20 @@
 			logger.Errorw("Cannot send ONU-G set", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send ONU-G-Set-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate ONU-G", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": 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(), "deviceId": 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{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
+	logger.Debugw("send UNI-G-Set-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
 
 	// UNI-G ME-ID is taken from Mib Upload stored OnuUniPort instance (argument)
 	meParams := me.ParamData{
@@ -975,21 +967,20 @@
 			logger.Errorw("Cannot send UNIG-G-Set", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send UNI-G-Set-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate UNI-G", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": 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(), "deviceId": 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{"deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
+	logger.Debugw("send VEIP-Set-msg:", log.Fields{"deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
 
 	// ONU-G ME-ID is defined to be 0, no need to perform a DB lookup
 	meParams := me.ParamData{
@@ -1021,22 +1012,21 @@
 			logger.Errorw("Cannot send VEIP-Set", log.Fields{
 				"Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debug("send VEIP-Set-msg done")
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate VEIP", log.Fields{
-			"Err": omciErr.GetError(), "deviceId": oo.deviceID})
-		return nil
+		logger.Debug("send VEIP-Set-msg done")
+		return meInstance
 	}
+	logger.Errorw("Cannot generate VEIP", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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, "deviceId": oo.deviceID, "SequNo": strconv.FormatInt(int64(tid), 16)})
+	logger.Debugw("send get-request-msg", log.Fields{"classID": classID, "deviceId": oo.deviceID,
+		"SequNo": strconv.FormatInt(int64(tid), 16)})
 
 	meParams := me.ParamData{
 		EntityID:   entityID,
@@ -1063,12 +1053,308 @@
 		if err != nil {
 			logger.Errorw("Cannot send get-request-msg", log.Fields{"meClassIdName": meClassIdName, "Err": err, "deviceId": oo.deviceID})
 			return nil
-		} else {
-			logger.Debugw("send get-request-msg done", log.Fields{"meClassIdName": meClassIdName, "deviceId": oo.deviceID})
-			return meInstance
 		}
-	} else {
-		logger.Errorw("Cannot generate meDefinition", log.Fields{"classID": classID, "Err": omciErr.GetError(), "deviceId": oo.deviceID})
-		return nil
+		logger.Debugw("send get-request-msg done", log.Fields{"meClassIdName": meClassIdName, "deviceId": oo.deviceID})
+		return meInstance
 	}
+	logger.Errorw("Cannot generate meDefinition", log.Fields{"classID": classID, "Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize .1pMapper create", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send .1pMapper-create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate .1pMapper", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize MBPCD create", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send MBPCD-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate MBPCD Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize GemNCTP create", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send GemNCTP-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate GemNCTP Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize GemIwTp create", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send GemIwTp-Create-msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate GemIwTp Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize TCont set", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send TCont-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate TCont Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize PrioQueue set", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send PrioQueue-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate PrioQueue Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": 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{"deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+
+		pkt, err := serializeOmciLayer(omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw("Cannot serialize 1PMapper set", log.Fields{
+				"Err": err, "deviceId": 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, "deviceId": oo.deviceID})
+			return nil
+		}
+		logger.Debug("send 1PMapper-set msg done")
+		return meInstance
+	}
+	logger.Errorw("Cannot generate 1PMapper Instance", log.Fields{
+		"Err": omciErr.GetError(), "deviceId": oo.deviceID})
+	return nil
 }
diff --git a/internal/pkg/onuadaptercore/onu_device_entry.go b/internal/pkg/onuadaptercore/onu_device_entry.go
index 9b453ce..a08e03f 100644
--- a/internal/pkg/onuadaptercore/onu_device_entry.go
+++ b/internal/pkg/onuadaptercore/onu_device_entry.go
@@ -53,6 +53,7 @@
 	UniAdminStateDone    OnuDeviceEvent = 6 // Uni ports admin set done - general
 	PortLinkUp           OnuDeviceEvent = 7 // Port link state change
 	PortLinkDw           OnuDeviceEvent = 8 // Port link state change
+	OmciAniConfigDone    OnuDeviceEvent = 9 // AniSide config according to TechProfile done
 	// Add other events here as needed (alarms separate???)
 )
 
diff --git a/internal/pkg/onuadaptercore/onu_uni_tp.go b/internal/pkg/onuadaptercore/onu_uni_tp.go
index 1539b9a..0ab7984 100644
--- a/internal/pkg/onuadaptercore/onu_uni_tp.go
+++ b/internal/pkg/onuadaptercore/onu_uni_tp.go
@@ -20,8 +20,11 @@
 import (
 	"context"
 	"encoding/json"
+	"strconv"
+	"strings"
 	"sync"
 
+	"github.com/looplab/fsm"
 	"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"
@@ -49,9 +52,39 @@
 	persAdminState string
 	persOperState  string
 	persUniTpPath  map[uint32]string
-	persUniTpData  map[uint32]tp.TechProfile
 }
 
+type tTechProfileIndication struct {
+	techProfileType string
+	techProfileID   uint16
+}
+
+type tcontParamStruct struct {
+	allocID     uint16
+	schedPolicy uint8
+}
+type gemPortParamStruct struct {
+	gemPortID       uint16
+	direction       uint8
+	gemPortEncState uint8
+	usedPbitMap     uint8
+	ponOmciCC       bool
+	discardPolicy   string
+	//could also be a queue specific paramter, not used that way here
+	maxQueueSize     uint16
+	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
@@ -59,6 +92,10 @@
 	tpProcMutex        sync.RWMutex
 	sOnuPersistentData onuPersistentData
 	techProfileKVStore *db.Backend
+	chTpProcessingStep chan uint8
+	mapUniTpIndication map[uint32]*tTechProfileIndication //use pointer values to ease assignments to the map
+	mapPonAniConfig    map[uint32]*tMapPonAniConfig       //per UNI: use pointer values to ease assignments to the map
+	pAniConfigFsm      *UniPonAniConfigFsm
 }
 
 //NewOnuUniTechProf returns the instance of a OnuUniTechProf
@@ -70,7 +107,9 @@
 	onuTP.baseDeviceHandler = aDeviceHandler
 	onuTP.tpProcMutex = sync.RWMutex{}
 	onuTP.sOnuPersistentData.persUniTpPath = make(map[uint32]string)
-	onuTP.sOnuPersistentData.persUniTpData = make(map[uint32]tp.TechProfile)
+	onuTP.chTpProcessingStep = make(chan uint8)
+	onuTP.mapUniTpIndication = make(map[uint32]*tTechProfileIndication)
+	onuTP.mapPonAniConfig = make(map[uint32]*tMapPonAniConfig)
 
 	onuTP.techProfileKVStore = aDeviceHandler.SetBackend(cBasePathTechProfileKVStore)
 	if onuTP.techProfileKVStore == nil {
@@ -132,72 +171,342 @@
 	return true
 }
 
-func (onuTP *OnuUniTechProf) configureUniTp(aUniID uint32, aPathString string, wg *sync.WaitGroup) {
-	defer wg.Done()
+func (onuTP *OnuUniTechProf) waitForTpCompletion(cancel context.CancelFunc, wg *sync.WaitGroup) {
+	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
+}
+
+// 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, processingStep) for internal synchronisation
+func (onuTP *OnuUniTechProf) configureUniTp(ctx context.Context,
+	aUniID uint32, aPathString string, wg *sync.WaitGroup) {
+	defer wg.Done() //always decrement the waitGroup on return
 	logger.Debugw("configure the Uni according to TpPath", log.Fields{
 		"deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
 
-	//TODO!!!
-	// reaction on existing tp, deletion of tp, start the corresponding OMCI configuation of the UNI port
-
 	if onuTP.techProfileKVStore == nil {
 		logger.Debug("techProfileKVStore not set - abort")
 		return
 	}
 
-	Value, err := onuTP.techProfileKVStore.Get(context.TODO(), aPathString)
-	if err == nil {
-		if Value != nil {
-			logger.Debugw("tech-profile read",
-				log.Fields{"Key": Value.Key, "Value": Value.Value})
-			tpTmpBytes, _ := kvstore.ToByte(Value.Value)
+	//ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
+	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})
+		return
+	}
 
-			var tpInst tp.TechProfile
-			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})
-			} else {
-				logger.Debugw("TechProf - tpInst", log.Fields{"tpInst": tpInst})
-				onuTP.sOnuPersistentData.persUniTpData[aUniID] = tpInst
+	var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpProcessingStep
 
-				// access examples
-				logger.Debugw("TechProf - name",
-					log.Fields{"onuTP.sOnuPersistentData.persUniTpData[aUniID].Name": onuTP.sOnuPersistentData.persUniTpData[aUniID].Name})
-				//
-				logger.Debugw("TechProf - instance_control.max_gem_payload_size",
-					log.Fields{"onuTP.sOnuPersistentData.persUniTpData[aUniID].InstanceCtrl.MaxGemPayloadSize": onuTP.sOnuPersistentData.persUniTpData[aUniID].InstanceCtrl.MaxGemPayloadSize})
-				//
-				logger.Debugw("TechProf - downstream_gem_port_attribute_list.discard_config.max_threshold",
-					log.Fields{"onuTP.sOnuPersistentData.persUniTpData[aUniID].DownstreamGemPortAttributeList[0].DiscardConfig.MaxThreshold": onuTP.sOnuPersistentData.persUniTpData[aUniID].DownstreamGemPortAttributeList[0].DiscardConfig.MaxThreshold})
+	//according to updateOnuUniTpPath() logic the assumption here is, that this configuration is only called
+	//  in case the KVPath has changed for the given UNI,
+	//  as T-Cont and Gem-Id's are dependent on TechProfile-Id this means, that possibly previously existing
+	//  (ANI) configuration of this port has to be removed first
+	//  (moreover in this case a possibly existing flow configuration is also not valid anymore and needs clean-up as well)
+	//  existence of configuration can be detected based on tp stored TCONT's
+	//TODO!!!:
+	/* if tcontMap  not empty {
+		go onuTP.deleteAniSideConfig(ctx, aUniID, processingStep)
+		if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+			//timeout or error detected
+			return
+		}
+		clear tcontMap
+	}
+
+	processingStep++
+	*/
+	go onuTP.readAniSideConfigFromTechProfile(ctx, aUniID, aPathString, processingStep)
+	if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+		//timeout or error detected
+		logger.Debugw("tech-profile related configuration aborted on read",
+			log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID})
+		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, processingStep) {
+				//timeout or error detected
+				logger.Debugw("tech-profile related configuration aborted on set",
+					log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID})
+				//this issue here means that the AniConfigFsm has not finished succesfully
+				//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("reset")
+				return
 			}
 		} else {
-			logger.Debugw("No tech-profile found", log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+			// 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{
+				"deviceID": onuTP.deviceID, "uniID": aUniID})
 		}
 	} else {
-		logger.Errorw("kvstore-get failed for path",
-			log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+		logger.Debugw("no PonAni data for this UNI found - abort", log.Fields{
+			"deviceID": onuTP.deviceID, "uniID": aUniID})
 	}
 }
 
-func (onuTP *OnuUniTechProf) updateOnuTpPathKvStore(wg *sync.WaitGroup) {
+func (onuTP *OnuUniTechProf) updateOnuTpPathKvStore(ctx context.Context, wg *sync.WaitGroup) {
 	defer wg.Done()
 	logger.Debugw("this would update the ONU's TpPath in KVStore", log.Fields{
 		"deviceID": onuTP.deviceID})
 	//TODO!!!
-	//make use of onuTP.sOnuPersistentData to store the TpPath to KVStore
+	//make use of onuTP.sOnuPersistentData to store the TpPath to KVStore - as background routine
+	/*
+		var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpProcessingStep
+		go onuTp.storePersistentData(ctx, processingStep)
+		if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+			//timeout or error detected
+			return
+		}
+	*/
 }
 
-// deleteTpRessource removes ressources from the ONU's specified Uni
-func (onuTP *OnuUniTechProf) deleteTpRessource(aUniID uint32, aPathString string,
-	aRessource resourceEntry, aEntryID uint32, wg *sync.WaitGroup) {
+// 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{
-		"deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString, "ressource": aRessource})
+		"deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString, "Resource": aResource})
 	//TODO!!!
+	//delete the given resource from ONU OMCI config and data base - as background routine
+	/*
+		var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpProcessingStep
+		go onuTp.deleteAniResource(ctx, processingStep)
+		if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+			//timeout or error detected
+			return
+		}
+	*/
 }
 
-func (onuTP *OnuUniTechProf) waitForTpCompletion(wg *sync.WaitGroup) {
-	wg.Wait()
-	logger.Debug("some TechProfile Processing completed")
-	onuTP.tpProcMutex.Unlock() //allow further TP related processing
+/* internal methods *********************/
+func (onuTP *OnuUniTechProf) readAniSideConfigFromTechProfile(
+	ctx context.Context, aUniID uint32, aPathString string, aProcessingStep uint8) {
+	var tpInst tp.TechProfile
+
+	//store profile type and identifier for later usage within the OMCI identifier and possibly ME setup
+	//pathstring is defined to be in the form of <ProfType>/<profID>/<Interface/../Identifier>
+	subStringSlice := strings.Split(aPathString, "/")
+	if len(subStringSlice) <= 2 {
+		logger.Errorw("invalid path name format",
+			log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+		onuTP.chTpProcessingStep <- 0 //error indication
+		return
+	}
+
+	//just some logical check to avoid unexpected behavior
+	//at this point it is assumed that a new TechProfile is assigned to the UNI
+	//expectation is that no TPIndication entry exists here, if yes,
+	//  then we throw a warning and remove it (and the possible ANIConfig) simply
+	//  note that the ONU config state may be ambivalent in such a case
+	//  also note, that the PonAniConfig map is not checked additionally
+	//    consistency to TPIndication is assumed
+	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.chTpProcessingStep <- 0 //error indication
+		return
+	}
+
+	//note the limitation on ID range (probably even more limited) - based on usage within OMCI EntityID
+	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(context.TODO(), 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.chTpProcessingStep <- 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.chTpProcessingStep <- 0 //error indication
+			return
+		}
+	} else {
+		logger.Errorw("kvstore-get failed for path",
+			log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
+		onuTP.chTpProcessingStep <- 0 //error indication
+		return
+	}
+
+	//for first start assume a 1Tcont1Gem profile, later extend for multi GemPerTcont and MultiTcontMultiGem
+	localMapGemPortParams := make(map[uint16]*gemPortParamStruct)
+	localMapGemPortParams[0] = &gemPortParamStruct{}
+	localMapPonAniConfig := make(map[uint16]*tcontGemList)
+	localMapPonAniConfig[0] = &tcontGemList{tcontParamStruct{}, localMapGemPortParams}
+	onuTP.mapPonAniConfig[aUniID] = (*tMapPonAniConfig)(&localMapPonAniConfig)
+
+	//get the relevant values from the profile and store to mapPonAniConfig
+	(*(onuTP.mapPonAniConfig[aUniID]))[0].tcontParams.allocID = uint16(tpInst.UsScheduler.AllocID)
+	//maybe tCont scheduling not (yet) needed - just to basicaly have it for future
+	//  (would only be relevant in case of ONU-2G QOS configuration flexibility)
+	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
+	}
+	for pos, content := range tpInst.UpstreamGemPortAttributeList {
+		if pos == 1 {
+			logger.Debugw("PonAniConfig abort GemPortList - still only one Gemport supported",
+				log.Fields{"device-id": onuTP.deviceID})
+			break
+		}
+		// a downstream GemPort should always exist (only downstream for MC)
+		(*(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
+		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)
+	}
+	//TODO!! MC (downstream) GemPorts can be set using DownstreamGemPortAttributeList seperately
+
+	//logger does not simply output the given structures, just give some example debug values
+	logger.Debugw("PonAniConfig read from TechProfile", log.Fields{
+		"device-id":       onuTP.deviceID,
+		"AllocId":         (*(onuTP.mapPonAniConfig[aUniID]))[0].tcontParams.allocID,
+		"GemPort":         (*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[0].gemPortID,
+		"QueueScheduling": (*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[0].queueSchedPolicy})
+
+	onuTP.chTpProcessingStep <- aProcessingStep //done
+}
+
+func (onuTP *OnuUniTechProf) setAniSideConfigFromTechProfile(
+	ctx context.Context, aUniID uint32, apCurrentUniPort *OnuUniPort, aProcessingStep uint8) {
+
+	//OMCI transfer of ANI data acc. to mapPonAniConfig
+	// also the FSM's are running in background,
+	//   hence we have to make sure they indicate 'success' success on chTpProcessingStep with aProcessingStep
+	if onuTP.pAniConfigFsm == nil {
+		onuTP.createAniConfigFsm(aUniID, apCurrentUniPort, OmciAniConfigDone, aProcessingStep)
+	} else { //AniConfigFsm already init
+		onuTP.runAniConfigFsm(aProcessingStep)
+	}
+}
+
+func (onuTP *OnuUniTechProf) waitForTimeoutOrCompletion(
+	ctx context.Context, aProcessingStep uint8) bool {
+	select {
+	case <-ctx.Done():
+		logger.Warnw("processing not completed in-time: force release of TpProcMutex!",
+			log.Fields{"deviceID": onuTP.deviceID, "error": ctx.Err()})
+		return false
+	case rxStep := <-onuTP.chTpProcessingStep:
+		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{"deviceID": onuTP.deviceID,
+				"wantedStep": aProcessingStep, "haveStep": rxStep})
+		return false
+	}
+}
+
+// createUniLockFsm initialises and runs the AniConfig FSM to transfer the OMCI related commands for ANI side configuration
+func (onuTP *OnuUniTechProf) createAniConfigFsm(aUniID uint32,
+	apCurrentUniPort *OnuUniPort, devEvent OnuDeviceEvent, aProcessingStep uint8) {
+	logger.Debugw("createAniConfigFsm", log.Fields{"deviceID": onuTP.deviceID})
+	chAniConfigFsm := make(chan Message, 2048)
+	pDevEntry := onuTP.baseDeviceHandler.GetOnuDeviceEntry(true)
+	if pDevEntry == nil {
+		logger.Errorw("No valid OnuDevice - aborting", log.Fields{"deviceID": 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{"deviceID": 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 *****
+	 */
+	var pACStatemachine *fsm.FSM
+	pACStatemachine = onuTP.pAniConfigFsm.pAdaptFsm.pFsm
+	if pACStatemachine != nil {
+		if pACStatemachine.Is("disabled") {
+			//FSM init requirement to get informed abou FSM completion! (otherwise timeout of the TechProf config)
+			onuTP.pAniConfigFsm.SetFsmCompleteChannel(onuTP.chTpProcessingStep, aProcessingStep)
+			if err := pACStatemachine.Event("start"); 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(), "deviceID": onuTP.deviceID})
+			}
+		} else {
+			logger.Warnw("wrong state of AniConfigFSM - want: disabled", log.Fields{
+				"have": pACStatemachine.Current(), "deviceID": onuTP.deviceID})
+			// maybe try a FSM reset and then again ... - TODO!!!
+		}
+	} else {
+		logger.Errorw("AniConfigFSM StateMachine invalid - cannot be executed!!", log.Fields{"deviceID": onuTP.deviceID})
+		// maybe try a FSM reset and then again ... - TODO!!!
+	}
 }
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
index 1c72b4c..3de061e 100644
--- a/internal/pkg/onuadaptercore/openonu.go
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -268,7 +268,9 @@
 
 //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 {
-	return errors.New("unImplemented")
+	//	return errors.New("unImplemented")
+	// testwise: just acknowledge to see, if that avoids ongoing TechProfile config sequences ...
+	return nil
 }
 
 //Update_pm_config returns PmConfigs nil or error