diff --git a/internal/pkg/uniprt/common.go b/internal/pkg/uniprt/common.go
new file mode 100755
index 0000000..3dcfe83
--- /dev/null
+++ b/internal/pkg/uniprt/common.go
@@ -0,0 +1,33 @@
+/*
+ * 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 uniprt provides the utilities for uni port configuration
+package uniprt
+
+import (
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{"pkg": "uniprt"})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/internal/pkg/uniprt/uniportadmin.go b/internal/pkg/uniprt/uniportadmin.go
new file mode 100755
index 0000000..a9de1dd
--- /dev/null
+++ b/internal/pkg/uniprt/uniportadmin.go
@@ -0,0 +1,507 @@
+/*
+ * 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 uniprt provides the utilities for uni port configuration
+package uniprt
+
+import (
+	"context"
+	"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/log"
+	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
+)
+
+//LockStateFsm defines the structure for the state machine to lock/unlock the ONU UNI ports via OMCI
+type LockStateFsm struct {
+	deviceID                 string
+	pDeviceHandler           cmn.IdeviceHandler
+	pOnuDeviceEntry          cmn.IonuDeviceEntry
+	pOmciCC                  *cmn.OmciCC
+	mutexAdminState          sync.RWMutex
+	adminState               bool
+	requestEvent             cmn.OnuDeviceEvent
+	omciLockResponseReceived chan bool //seperate channel needed for checking UNI port OMCi message responses
+	PAdaptFsm                *cmn.AdapterFsm
+	mutexPLastTxMeInstance   sync.RWMutex
+	pLastTxMeInstance        *me.ManagedEntity
+}
+
+// events of lock/unlock UNI port FSM
+const (
+	UniEvStart         = "UniEvStart"
+	UniEvStartAdmin    = "UniEvStartAdmin"
+	UniEvRxUnisResp    = "UniEvRxUnisResp"
+	UniEvRxOnugResp    = "UniEvRxOnugResp"
+	UniEvTimeoutSimple = "UniEvTimeoutSimple"
+	UniEvTimeoutUnis   = "UniEvTimeoutUnis"
+	UniEvReset         = "UniEvReset"
+	UniEvRestart       = "UniEvRestart"
+)
+
+// states of lock/unlock UNI port FSM
+const (
+	UniStDisabled    = "UniStDisabled"
+	UniStStarting    = "UniStStarting"
+	UniStSettingUnis = "UniStSettingUnis"
+	UniStSettingOnuG = "UniStSettingOnuG"
+	UniStAdminDone   = "UniStAdminDone"
+	UniStResetting   = "UniStResetting"
+)
+
+// CUniFsmIdleState - TODO: add comment
+const CUniFsmIdleState = UniStDisabled
+
+//NewLockStateFsm is the 'constructor' for the state machine to lock/unlock the ONU UNI ports via OMCI
+func NewLockStateFsm(ctx context.Context, aAdminState bool, aRequestEvent cmn.OnuDeviceEvent,
+	aName string, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, aCommChannel chan cmn.Message) *LockStateFsm {
+	instFsm := &LockStateFsm{
+		deviceID:        apDeviceHandler.GetDeviceID(),
+		pDeviceHandler:  apDeviceHandler,
+		pOnuDeviceEntry: apOnuDeviceEntry,
+		pOmciCC:         apOnuDeviceEntry.GetDevOmciCC(),
+		adminState:      aAdminState,
+		requestEvent:    aRequestEvent,
+	}
+	instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
+	if instFsm.PAdaptFsm == nil {
+		logger.Errorw(ctx, "LockStateFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
+			"device-id": instFsm.deviceID})
+		return nil
+	}
+	if aAdminState { //port locking requested
+		instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
+			UniStDisabled,
+			fsm.Events{
+
+				{Name: UniEvStart, Src: []string{UniStDisabled}, Dst: UniStStarting},
+
+				{Name: UniEvStartAdmin, Src: []string{UniStStarting}, Dst: UniStSettingUnis},
+				// the settingUnis state is used for multi ME config for all UNI related ports
+				// maybe such could be reflected in the state machine as well (port number parametrized)
+				// but that looks not straightforward here - so we keep it simple here for the beginning(?)
+				{Name: UniEvRxUnisResp, Src: []string{UniStSettingUnis}, Dst: UniStSettingOnuG},
+				{Name: UniEvRxOnugResp, Src: []string{UniStSettingOnuG}, Dst: UniStAdminDone},
+
+				{Name: UniEvTimeoutSimple, Src: []string{UniStSettingOnuG}, Dst: UniStStarting},
+				{Name: UniEvTimeoutUnis, Src: []string{UniStSettingUnis}, Dst: UniStStarting},
+
+				{Name: UniEvReset, Src: []string{UniStStarting, UniStSettingOnuG, UniStSettingUnis,
+					UniStAdminDone}, Dst: UniStResetting},
+				// exceptional treatment for all states except UniStResetting
+				{Name: UniEvRestart, Src: []string{UniStStarting, UniStSettingOnuG, UniStSettingUnis,
+					UniStAdminDone, UniStResetting}, Dst: UniStDisabled},
+			},
+
+			fsm.Callbacks{
+				"enter_state":                 func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
+				("enter_" + UniStStarting):    func(e *fsm.Event) { instFsm.enterAdminStartingState(ctx, e) },
+				("enter_" + UniStSettingOnuG): func(e *fsm.Event) { instFsm.enterSettingOnuGState(ctx, e) },
+				("enter_" + UniStSettingUnis): func(e *fsm.Event) { instFsm.enterSettingUnisState(ctx, e) },
+				("enter_" + UniStAdminDone):   func(e *fsm.Event) { instFsm.enterAdminDoneState(ctx, e) },
+				("enter_" + UniStResetting):   func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
+			},
+		)
+	} else { //port unlocking requested
+		instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
+			UniStDisabled,
+			fsm.Events{
+
+				{Name: UniEvStart, Src: []string{UniStDisabled}, Dst: UniStStarting},
+
+				{Name: UniEvStartAdmin, Src: []string{UniStStarting}, Dst: UniStSettingOnuG},
+				{Name: UniEvRxOnugResp, Src: []string{UniStSettingOnuG}, Dst: UniStSettingUnis},
+				// the settingUnis state is used for multi ME config for all UNI related ports
+				// maybe such could be reflected in the state machine as well (port number parametrized)
+				// but that looks not straightforward here - so we keep it simple here for the beginning(?)
+				{Name: UniEvRxUnisResp, Src: []string{UniStSettingUnis}, Dst: UniStAdminDone},
+
+				{Name: UniEvTimeoutSimple, Src: []string{UniStSettingOnuG}, Dst: UniStStarting},
+				{Name: UniEvTimeoutUnis, Src: []string{UniStSettingUnis}, Dst: UniStStarting},
+
+				{Name: UniEvReset, Src: []string{UniStStarting, UniStSettingOnuG, UniStSettingUnis,
+					UniStAdminDone}, Dst: UniStResetting},
+				// exceptional treatment for all states except UniStResetting
+				{Name: UniEvRestart, Src: []string{UniStStarting, UniStSettingOnuG, UniStSettingUnis,
+					UniStAdminDone, UniStResetting}, Dst: UniStDisabled},
+			},
+
+			fsm.Callbacks{
+				"enter_state":                 func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
+				("enter_" + UniStStarting):    func(e *fsm.Event) { instFsm.enterAdminStartingState(ctx, e) },
+				("enter_" + UniStSettingOnuG): func(e *fsm.Event) { instFsm.enterSettingOnuGState(ctx, e) },
+				("enter_" + UniStSettingUnis): func(e *fsm.Event) { instFsm.enterSettingUnisState(ctx, e) },
+				("enter_" + UniStAdminDone):   func(e *fsm.Event) { instFsm.enterAdminDoneState(ctx, e) },
+				("enter_" + UniStResetting):   func(e *fsm.Event) { instFsm.enterResettingState(ctx, e) },
+			},
+		)
+	}
+	if instFsm.PAdaptFsm.PFsm == nil {
+		logger.Errorw(ctx, "LockStateFsm's Base FSM could not be instantiated!!", log.Fields{
+			"device-id": instFsm.deviceID})
+		return nil
+	}
+
+	logger.Debugw(ctx, "LockStateFsm created", log.Fields{"device-id": instFsm.deviceID})
+	return instFsm
+}
+
+//SetSuccessEvent modifies the requested event notified on success
+//assumption is that this is only called in the disabled (idle) state of the FSM, hence no sem protection required
+func (oFsm *LockStateFsm) SetSuccessEvent(aEvent cmn.OnuDeviceEvent) {
+	oFsm.requestEvent = aEvent
+}
+
+func (oFsm *LockStateFsm) enterAdminStartingState(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "LockStateFSM start", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.deviceID})
+	// in case the used channel is not yet defined (can be re-used after restarts)
+	if oFsm.omciLockResponseReceived == nil {
+		oFsm.omciLockResponseReceived = make(chan bool)
+		logger.Debug(ctx, "LockStateFSM - OMCI UniLock RxChannel defined")
+	} else {
+		// as we may 're-use' this instance of FSM and the connected channel
+		// make sure there is no 'lingering' request in the already existing channels:
+		// (simple loop sufficient as we are the only receiver)
+		for len(oFsm.omciLockResponseReceived) > 0 {
+			<-oFsm.omciLockResponseReceived
+		}
+		for len(oFsm.PAdaptFsm.CommChan) > 0 {
+			<-oFsm.PAdaptFsm.CommChan
+		}
+	}
+	// start go routine for processing of LockState messages
+	go oFsm.processOmciLockMessages(ctx)
+
+	//let the state machine run forward from here directly
+	pLockStateAFsm := oFsm.PAdaptFsm
+	if pLockStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UniEvStartAdmin)
+			}
+		}(pLockStateAFsm)
+	}
+}
+
+func (oFsm *LockStateFsm) enterSettingOnuGState(ctx context.Context, e *fsm.Event) {
+	var omciAdminState uint8 = 1 //default locked
+	oFsm.mutexAdminState.RLock()
+	if !oFsm.adminState {
+		omciAdminState = 0
+	}
+	oFsm.mutexAdminState.RUnlock()
+	logger.Debugw(ctx, "LockStateFSM Tx Set::ONU-G:admin", log.Fields{
+		"omciAdmin": omciAdminState, "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
+	requestedAttributes := me.AttributeValueMap{"AdministrativeState": omciAdminState}
+	oFsm.mutexPLastTxMeInstance.Lock()
+	meInstance, err := oFsm.pOmciCC.SendSetOnuGLS(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
+		requestedAttributes, oFsm.PAdaptFsm.CommChan)
+	if err != nil {
+		oFsm.mutexPLastTxMeInstance.Unlock()
+		logger.Errorw(ctx, "OnuGLS set failed, aborting LockStateFSM", log.Fields{"device-id": oFsm.deviceID})
+		pLockStateAFsm := oFsm.PAdaptFsm
+		if pLockStateAFsm != nil {
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+					_ = a_pAFsm.PFsm.Event(UniEvReset)
+				}
+			}(pLockStateAFsm)
+		}
+		return
+	}
+	//accept also nil as (error) return value for writing to LastTx
+	//  - this avoids misinterpretation of new received OMCI messages
+	oFsm.pLastTxMeInstance = meInstance
+	if oFsm.pLastTxMeInstance == nil {
+		oFsm.mutexPLastTxMeInstance.Unlock()
+		logger.Errorw(ctx, "could not send OMCI message from LockStateFsm", log.Fields{
+			"device-id": oFsm.deviceID})
+		//some more sophisticated approach is possible, e.g. repeating once, by now let's reset the state machine in order to release all resources now
+		pLockStateAFsm := oFsm.PAdaptFsm
+		if pLockStateAFsm != nil {
+
+			// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+					_ = a_pAFsm.PFsm.Event(UniEvReset)
+				}
+			}(pLockStateAFsm)
+		}
+		return
+	}
+	oFsm.mutexPLastTxMeInstance.Unlock()
+}
+
+func (oFsm *LockStateFsm) enterSettingUnisState(ctx context.Context, e *fsm.Event) {
+	oFsm.mutexAdminState.RLock()
+	logger.Debugw(ctx, "LockStateFSM - starting UniTP adminState loop", log.Fields{
+		"in state": e.FSM.Current(), "device-id": oFsm.deviceID, "LockState": oFsm.adminState})
+	oFsm.mutexAdminState.RUnlock()
+	go oFsm.performUniPortAdminSet(ctx)
+}
+
+func (oFsm *LockStateFsm) enterAdminDoneState(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "LockStateFSM", log.Fields{"send notification to core in State": e.FSM.Current(), "device-id": oFsm.deviceID})
+	//use DeviceHandler event notification directly, no need/support to update DeviceEntryState for lock/unlock
+	oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, oFsm.requestEvent)
+
+	//let's reset the state machine in order to release all resources now
+	pLockStateAFsm := oFsm.PAdaptFsm
+	if pLockStateAFsm != nil {
+		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UniEvReset)
+			}
+		}(pLockStateAFsm)
+	}
+}
+
+func (oFsm *LockStateFsm) enterResettingState(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "LockStateFSM resetting", log.Fields{"device-id": oFsm.deviceID})
+	pLockStateAFsm := oFsm.PAdaptFsm
+	if pLockStateAFsm != nil {
+		// abort running message processing
+		fsmAbortMsg := cmn.Message{
+			Type: cmn.TestMsg,
+			Data: cmn.TestMessage{
+				TestMessageVal: cmn.AbortMessageProcessing,
+			},
+		}
+		pLockStateAFsm.CommChan <- fsmAbortMsg
+
+		//try to restart the FSM to 'disabled'
+		// see DownloadedState: decouple event transfer
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UniEvRestart)
+			}
+		}(pLockStateAFsm)
+		oFsm.mutexPLastTxMeInstance.Lock()
+		oFsm.pLastTxMeInstance = nil
+		oFsm.mutexPLastTxMeInstance.Unlock()
+	}
+}
+
+func (oFsm *LockStateFsm) processOmciLockMessages(ctx context.Context) {
+	logger.Debugw(ctx, "Start LockStateFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
+loop:
+	for {
+		// case <-ctx.Done():
+		// 	logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
+		// 	break loop
+		message, ok := <-oFsm.PAdaptFsm.CommChan
+		if !ok {
+			logger.Info(ctx, "LockStateFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
+			// but then we have to ensure a restart of the FSM as well - as exceptional procedure
+			_ = oFsm.PAdaptFsm.PFsm.Event(UniEvRestart)
+			break loop
+		}
+		logger.Debugw(ctx, "LockStateFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
+
+		switch message.Type {
+		case cmn.TestMsg:
+			msg, _ := message.Data.(cmn.TestMessage)
+			if msg.TestMessageVal == cmn.AbortMessageProcessing {
+				logger.Debugw(ctx, "LockStateFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
+				break loop
+			}
+			logger.Warnw(ctx, "LockStateFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
+		case cmn.OMCI:
+			msg, _ := message.Data.(cmn.OmciMessage)
+			oFsm.handleOmciLockStateMessage(ctx, msg)
+		default:
+			logger.Warn(ctx, "LockStateFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
+				"message.Type": message.Type})
+		}
+	}
+	logger.Debugw(ctx, "End LockStateFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
+}
+
+func (oFsm *LockStateFsm) handleOmciLockStateMessage(ctx context.Context, msg cmn.OmciMessage) {
+	logger.Debugw(ctx, "Rx OMCI LockStateFsm Msg", log.Fields{"device-id": oFsm.deviceID,
+		"msgType": msg.OmciMsg.MessageType})
+
+	if msg.OmciMsg.MessageType == omci.SetResponseType {
+		msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
+		if msgLayer == nil {
+			logger.Errorw(ctx, "LockStateFsm - Omci Msg layer could not be detected for SetResponse",
+				log.Fields{"device-id": oFsm.deviceID})
+			return
+		}
+		msgObj, msgOk := msgLayer.(*omci.SetResponse)
+		if !msgOk {
+			logger.Errorw(ctx, "LockStateFsm - Omci Msg layer could not be assigned for SetResponse",
+				log.Fields{"device-id": oFsm.deviceID})
+			return
+		}
+		logger.Debugw(ctx, "LockStateFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
+		if msgObj.Result != me.Success {
+			logger.Errorw(ctx, "LockStateFsm - Omci SetResponse Error - later: drive FSM to abort state ?", log.Fields{"Error": msgObj.Result})
+			// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+			return
+		}
+
+		//should never appear, left here for robustness
+		oFsm.mutexPLastTxMeInstance.RLock()
+		if oFsm.pLastTxMeInstance != nil {
+			// compare comments above for CreateResponse (apply also here ...)
+			if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
+				msgObj.EntityInstance == oFsm.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.pLastTxMeInstance.GetName() {
+				case "OnuG":
+					{ // let the FSM proceed ...
+						oFsm.mutexPLastTxMeInstance.RUnlock()
+						_ = oFsm.PAdaptFsm.PFsm.Event(UniEvRxOnugResp)
+					}
+				case "PhysicalPathTerminationPointEthernetUni", "VirtualEthernetInterfacePoint":
+					{ // let the PPTP init proceed by stopping the wait function
+						oFsm.mutexPLastTxMeInstance.RUnlock()
+						oFsm.omciLockResponseReceived <- true
+					}
+				default:
+					{
+						logger.Warnw(ctx, "Unsupported ME name received!",
+							log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
+						oFsm.mutexPLastTxMeInstance.RUnlock()
+					}
+				}
+			} else {
+				oFsm.mutexPLastTxMeInstance.RUnlock()
+				logger.Warnf(ctx, "LockStateFsm - Received SetResponse Data for %s with wrong classID or entityID ",
+					log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj}, msgObj.EntityClass)
+			}
+		} else {
+			oFsm.mutexPLastTxMeInstance.RUnlock()
+			logger.Errorw(ctx, "pLastTxMeInstance is nil", log.Fields{"device-id": oFsm.deviceID})
+			return
+		}
+	} else {
+		logger.Errorw(ctx, "LockStateFsm - Rx OMCI unhandled MsgType", log.Fields{"omciMsgType": msg.OmciMsg.MessageType})
+		return
+	}
+}
+
+func (oFsm *LockStateFsm) performUniPortAdminSet(ctx context.Context) {
+	var omciAdminState uint8 = 1 //default locked
+	oFsm.mutexAdminState.RLock()
+	if !oFsm.adminState {
+		omciAdminState = 0
+	}
+	oFsm.mutexAdminState.RUnlock()
+	//set PPTPEthUni or VEIP AdminState
+	requestedAttributes := me.AttributeValueMap{"AdministrativeState": omciAdminState}
+
+	for uniNo, uniPort := range *oFsm.pDeviceHandler.GetUniEntityMap() {
+		// only unlock the UniPort in case it is defined for usage (R2.6 limit only one port),
+		// compare also limitation for logical voltha port in dh.EnableUniPortStateUpdate()
+
+		if (omciAdminState == 1) || (1<<uniPort.UniID)&oFsm.pDeviceHandler.GetUniPortMask() == (1<<uniPort.UniID) {
+			var meInstance *me.ManagedEntity
+			if uniPort.PortType == cmn.UniPPTP {
+				logger.Debugw(ctx, "Setting PPTP admin state", log.Fields{
+					"device-id": oFsm.deviceID, "for PortNo": uniNo, "state (0-unlock)": omciAdminState})
+				oFsm.mutexPLastTxMeInstance.Lock()
+				meInstance, err := oFsm.pOmciCC.SendSetPptpEthUniLS(log.WithSpanFromContext(context.TODO(), ctx),
+					uniPort.EntityID, oFsm.pDeviceHandler.GetOmciTimeout(),
+					true, requestedAttributes, oFsm.PAdaptFsm.CommChan)
+				if err != nil {
+					oFsm.mutexPLastTxMeInstance.Unlock()
+					logger.Errorw(ctx, "SetPptpEthUniLS set failed, aborting LockStateFsm!",
+						log.Fields{"device-id": oFsm.deviceID})
+					_ = oFsm.PAdaptFsm.PFsm.Event(UniEvReset)
+					return
+				}
+				oFsm.pLastTxMeInstance = meInstance
+				oFsm.mutexPLastTxMeInstance.Unlock()
+			} else if uniPort.PortType == cmn.UniVEIP {
+				logger.Debugw(ctx, "Setting VEIP admin state", log.Fields{
+					"device-id": oFsm.deviceID, "for PortNo": uniNo, "state (0-unlock)": omciAdminState})
+				oFsm.mutexPLastTxMeInstance.Lock()
+				meInstance, err := oFsm.pOmciCC.SendSetVeipLS(log.WithSpanFromContext(context.TODO(), ctx),
+					uniPort.EntityID, oFsm.pDeviceHandler.GetOmciTimeout(),
+					true, requestedAttributes, oFsm.PAdaptFsm.CommChan)
+				if err != nil {
+					oFsm.mutexPLastTxMeInstance.Unlock()
+					logger.Errorw(ctx, "SetVeipLS set failed, aborting LockStateFsm!",
+						log.Fields{"device-id": oFsm.deviceID})
+					_ = oFsm.PAdaptFsm.PFsm.Event(UniEvReset)
+					return
+				}
+				oFsm.pLastTxMeInstance = meInstance
+				oFsm.mutexPLastTxMeInstance.Unlock()
+			} else {
+				logger.Warnw(ctx, "Unsupported UniTP type - skip",
+					log.Fields{"device-id": oFsm.deviceID, "Port": uniNo})
+				continue
+			}
+			oFsm.mutexPLastTxMeInstance.RLock()
+			if oFsm.pLastTxMeInstance == nil {
+				oFsm.mutexPLastTxMeInstance.RUnlock()
+				logger.Errorw(ctx, "could not send PortAdmin OMCI message from LockStateFsm", log.Fields{
+					"device-id": oFsm.deviceID, "Port": uniNo})
+				//some more sophisticated approach is possible, e.g. repeating once, by now let's reset the state machine in order to release all resources now
+				_ = oFsm.PAdaptFsm.PFsm.Event(UniEvReset)
+				return
+			}
+			oFsm.mutexPLastTxMeInstance.RUnlock()
+
+			//verify response
+			err := oFsm.waitforOmciResponse(ctx, meInstance)
+			if err != nil {
+				logger.Errorw(ctx, "UniTP Admin State set failed, aborting LockState set!",
+					log.Fields{"device-id": oFsm.deviceID, "Port": uniNo})
+				_ = oFsm.PAdaptFsm.PFsm.Event(UniEvReset)
+				return
+			}
+		}
+	} //for all UNI ports
+	// if Config has been done for all UNI related instances let the FSM proceed
+	// while we did not check here, if there is some port at all - !?
+	logger.Infow(ctx, "UniTP adminState loop finished", log.Fields{"device-id": oFsm.deviceID})
+	_ = oFsm.PAdaptFsm.PFsm.Event(UniEvRxUnisResp)
+}
+
+func (oFsm *LockStateFsm) waitforOmciResponse(ctx context.Context, apMeInstance *me.ManagedEntity) error {
+	select {
+	// maybe be also some outside cancel (but no context modeled for the moment ...)
+	// case <-ctx.Done():
+	// 		logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
+	case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw(ctx, "lockStateFSM uni-set timeout", log.Fields{"for device-id": oFsm.deviceID})
+		return fmt.Errorf("lockStateFsm uni-set timeout for device-id %s", oFsm.deviceID)
+	case success := <-oFsm.omciLockResponseReceived:
+		if success {
+			logger.Debug(ctx, "LockStateFSM uni-set response received")
+			return nil
+		}
+		// should not happen so far
+		logger.Warnw(ctx, "lockStateFSM uni-set response error", log.Fields{"for device-id": oFsm.deviceID})
+		return fmt.Errorf("lockStateFsm uni-set responseError for device-id %s", oFsm.deviceID)
+	}
+}
diff --git a/internal/pkg/uniprt/uniportstatus.go b/internal/pkg/uniprt/uniportstatus.go
new file mode 100755
index 0000000..8f8dedd
--- /dev/null
+++ b/internal/pkg/uniprt/uniportstatus.go
@@ -0,0 +1,175 @@
+/*
+ * 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 uniprt provides the utilities for uni port configuration
+package uniprt
+
+import (
+	"context"
+	"time"
+
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
+	"github.com/opencord/voltha-protos/v5/go/extension"
+)
+
+const (
+	uniStatusTimeout = 3
+	adminState       = "AdministrativeState"
+	operationalState = "OperationalState"
+	configInd        = "ConfigurationInd"
+)
+
+//UniPortStatus implements methods to get uni port status info
+type UniPortStatus struct {
+	pDeviceHandler    cmn.IdeviceHandler
+	pOmiCC            *cmn.OmciCC
+	omciRespChn       chan cmn.Message
+	pLastTxMeInstance *me.ManagedEntity
+}
+
+//NewUniPortStatus creates a new instance of UniPortStatus
+func NewUniPortStatus(apDeviceHandler cmn.IdeviceHandler, apOmicc *cmn.OmciCC) *UniPortStatus {
+	return &UniPortStatus{
+		pDeviceHandler: apDeviceHandler,
+		pOmiCC:         apOmicc,
+		omciRespChn:    make(chan cmn.Message),
+	}
+
+}
+
+// GetUniPortStatus - TODO: add comment
+func (portStatus *UniPortStatus) GetUniPortStatus(ctx context.Context, uniIdx uint32) *extension.SingleGetValueResponse {
+	for _, uniPort := range *portStatus.pDeviceHandler.GetUniEntityMap() {
+
+		if uniPort.UniID == uint8(uniIdx) && uniPort.PortType == cmn.UniPPTP {
+
+			requestedAttributes := me.AttributeValueMap{adminState: 0, operationalState: 0, configInd: 0}
+			// Note: No reference to fetch the OMCI timeout configuration value, so hard code it to 10s
+			meInstance, err := portStatus.pOmiCC.SendGetMe(ctx, me.PhysicalPathTerminationPointEthernetUniClassID, uniPort.EntityID, requestedAttributes, 10, true, portStatus.omciRespChn)
+			if err != nil {
+				return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+			}
+			if meInstance != nil {
+				portStatus.pLastTxMeInstance = meInstance
+
+				//verify response
+				return portStatus.waitforGetUniPortStatus(ctx, meInstance)
+			}
+		}
+	}
+	logger.Errorw(ctx, "GetUniPortStatus uniIdx is not valid", log.Fields{"uniIdx": uniIdx})
+	return PostUniStatusErrResponse(extension.GetValueResponse_INVALID_PORT_TYPE)
+}
+
+func (portStatus *UniPortStatus) waitforGetUniPortStatus(ctx context.Context, apMeInstance *me.ManagedEntity) *extension.SingleGetValueResponse {
+
+	select {
+	// maybe be also some outside cancel (but no context modeled for the moment ...)
+	case <-ctx.Done():
+		logger.Errorf(ctx, "waitforGetUniPortStatus Context done")
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+	case <-time.After(uniStatusTimeout * time.Second):
+		logger.Errorf(ctx, "waitforGetUniPortStatus  timeout")
+		return PostUniStatusErrResponse(extension.GetValueResponse_TIMEOUT)
+
+	case omciMsg := <-portStatus.omciRespChn:
+		if omciMsg.Type != cmn.OMCI {
+			return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+		}
+		msg, _ := omciMsg.Data.(cmn.OmciMessage)
+		return portStatus.processGetUnitStatusResp(ctx, msg)
+	}
+
+}
+
+func (portStatus *UniPortStatus) processGetUnitStatusResp(ctx context.Context, msg cmn.OmciMessage) *extension.SingleGetValueResponse {
+	logger.Debugw(ctx, "processGetUniStatusResp:", log.Fields{"msg.Omci.MessageType": msg.OmciMsg.MessageType,
+		"msg.OmciMsg.TransactionID": msg.OmciMsg.TransactionID, "DeviceIdentfier": msg.OmciMsg.DeviceIdentifier})
+
+	if msg.OmciMsg.MessageType != omci.GetResponseType {
+		logger.Debugw(ctx, "processGetUniStatusResp error", log.Fields{"incorrect RespType": msg.OmciMsg.MessageType,
+			"expected": omci.GetResponseType})
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+	}
+
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
+	if msgLayer == nil {
+		logger.Errorf(ctx, "processGetUniStatusResp omci Msg layer not found - ")
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+
+	}
+	msgObj, msgOk := msgLayer.(*omci.GetResponse)
+	if !msgOk {
+		logger.Errorf(ctx, "processGetUniStatusResp omci msgObj layer could not be found ")
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+
+	}
+
+	if msgObj.Result != me.Success {
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
+	}
+	meAttributes := msgObj.Attributes
+
+	singleValResp := extension.SingleGetValueResponse{
+		Response: &extension.GetValueResponse{
+			Status: extension.GetValueResponse_OK,
+			Response: &extension.GetValueResponse_UniInfo{
+				UniInfo: &extension.GetOnuUniInfoResponse{},
+			},
+		},
+	}
+	if meAttributes[operationalState].(uint8) == 0 {
+		singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_ENABLED
+	} else if meAttributes[operationalState].(uint8) == 1 {
+		singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_DISABLED
+	} else {
+		singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_OPERSTATE_UNDEFINED
+	}
+
+	if meAttributes[adminState].(uint8) == 0 {
+		singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_UNLOCKED
+	} else if meAttributes[adminState].(uint8) == 1 {
+		singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_LOCKED
+	} else {
+		singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_ADMSTATE_UNDEFINED
+	}
+	configIndMap := map[uint8]extension.GetOnuUniInfoResponse_ConfigurationInd{
+		0:  0,
+		1:  extension.GetOnuUniInfoResponse_TEN_BASE_T_FDX,
+		2:  extension.GetOnuUniInfoResponse_HUNDRED_BASE_T_FDX,
+		3:  extension.GetOnuUniInfoResponse_GIGABIT_ETHERNET_FDX,
+		4:  extension.GetOnuUniInfoResponse_TEN_G_ETHERNET_FDX,
+		17: extension.GetOnuUniInfoResponse_TEN_BASE_T_HDX,
+		18: extension.GetOnuUniInfoResponse_HUNDRED_BASE_T_HDX,
+		19: extension.GetOnuUniInfoResponse_GIGABIT_ETHERNET_HDX,
+	}
+	configInd := meAttributes[configInd].(uint8)
+	singleValResp.Response.GetUniInfo().ConfigInd = configIndMap[configInd]
+	return &singleValResp
+}
+
+// PostUniStatusErrResponse - TODO: add comment
+func PostUniStatusErrResponse(reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
+	return &extension.SingleGetValueResponse{
+		Response: &extension.GetValueResponse{
+			Status:    extension.GetValueResponse_ERROR,
+			ErrReason: reason,
+		},
+	}
+}
