[VOL-4631] openonuAdapterGo - hardening: check ONU OMCI get responses for consistency

Change-Id: I6402b16408fd29db8d95f1607ff1af21da5907de
diff --git a/VERSION b/VERSION
index c4d784e..2e369c9 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.2-dev273
+2.2.2-dev274
diff --git a/internal/pkg/common/defines.go b/internal/pkg/common/defines.go
index 06bc4b2..14ad286 100755
--- a/internal/pkg/common/defines.go
+++ b/internal/pkg/common/defines.go
@@ -332,6 +332,7 @@
 	IPHostConfigDataMeID = 1
 	OnugSerialNumberLen  = 8
 	OmciMacAddressLen    = 6
+	MdsDefaultMib        = 0
 )
 
 ///////////////////////////////////////////////////////////
diff --git a/internal/pkg/common/interfaces.go b/internal/pkg/common/interfaces.go
index a204539..7317a35 100755
--- a/internal/pkg/common/interfaces.go
+++ b/internal/pkg/common/interfaces.go
@@ -141,7 +141,7 @@
 	IncrementMibDataSync(context.Context)
 
 	GetActiveImageMeID(context.Context) (uint16, error)
-	HandleSwImageIndications(context.Context, uint16, me.AttributeValueMap)
+	HandleSwImageIndications(context.Context, uint16, me.AttributeValueMap) bool
 	GetPersActiveSwVersion() string
 	SetPersActiveSwVersion(string)
 	GetActiveImageVersion(context.Context) string
diff --git a/internal/pkg/mib/mib_sync.go b/internal/pkg/mib/mib_sync.go
index 4fd5ebb..c839d45 100755
--- a/internal/pkg/mib/mib_sync.go
+++ b/internal/pkg/mib/mib_sync.go
@@ -499,7 +499,7 @@
 				logger.Debugw(ctx, "MibResetResponse Data", log.Fields{"data-fields": msgObj})
 				if msgObj.Result == me.Success {
 					oo.MutexPersOnuConfig.Lock()
-					oo.SOnuPersistentData.PersMibDataSyncAdpt = 0
+					oo.SOnuPersistentData.PersMibDataSyncAdpt = cmn.MdsDefaultMib
 					oo.MutexPersOnuConfig.Unlock()
 					// trigger retrieval of VendorId and SerialNumber
 					_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetVendorAndSerial)
@@ -690,30 +690,63 @@
 			switch meInstance {
 			case "OnuG":
 				oo.mutexLastTxParamStruct.RUnlock()
-				oo.MutexPersOnuConfig.Lock()
-				oo.SOnuPersistentData.PersVendorID = cmn.TrimStringFromMeOctet(meAttributes[me.OnuG_VendorId])
-				snBytes, _ := me.InterfaceToOctets(meAttributes[me.OnuG_SerialNumber])
-				if cmn.OnugSerialNumberLen == len(snBytes) {
-					snVendorPart := fmt.Sprintf("%s", snBytes[:4])
-					snNumberPart := hex.EncodeToString(snBytes[4:])
-					oo.SOnuPersistentData.PersSerialNumber = snVendorPart + snNumberPart
-					logger.Debugw(ctx, "MibSync FSM - GetResponse Data for Onu-G - VendorId/SerialNumber", log.Fields{"device-id": oo.deviceID,
-						"onuDeviceEntry.vendorID": oo.SOnuPersistentData.PersVendorID, "onuDeviceEntry.serialNumber": oo.SOnuPersistentData.PersSerialNumber})
+				if onuGVendorID, ok := meAttributes[me.OnuG_VendorId]; ok {
+					vendorID := cmn.TrimStringFromMeOctet(onuGVendorID)
+					if vendorID == "" {
+						logger.Infow(ctx, "MibSync FSM - mandatory attribute VendorId is empty in OnuG instance - fill with appropriate value", log.Fields{"device-id": oo.deviceID})
+						vendorID = cEmptyVendorIDString
+					}
+					oo.MutexPersOnuConfig.Lock()
+					oo.SOnuPersistentData.PersVendorID = vendorID
+					oo.MutexPersOnuConfig.Unlock()
 				} else {
-					logger.Infow(ctx, "MibSync FSM - SerialNumber has wrong length - fill serialNumber with zeros", log.Fields{"device-id": oo.deviceID, "length": len(snBytes)})
-					oo.SOnuPersistentData.PersSerialNumber = cEmptySerialNumberString
+					logger.Errorw(ctx, "MibSync FSM - mandatory attribute VendorId not present in OnuG instance - handling of MibSyncChan stopped!",
+						log.Fields{"device-id": oo.deviceID})
+					_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
+					return fmt.Errorf("mibSync FSM - mandatory attribute VendorId not present in OnuG instance - handling of MibSyncChan stopped: %s", oo.deviceID)
 				}
-				oo.MutexPersOnuConfig.Unlock()
+				if onuGSerialNumber, ok := meAttributes[me.OnuG_SerialNumber]; ok {
+					oo.MutexPersOnuConfig.Lock()
+					snBytes, _ := me.InterfaceToOctets(onuGSerialNumber)
+					if cmn.OnugSerialNumberLen == len(snBytes) {
+						snVendorPart := fmt.Sprintf("%s", snBytes[:4])
+						snNumberPart := hex.EncodeToString(snBytes[4:])
+						oo.SOnuPersistentData.PersSerialNumber = snVendorPart + snNumberPart
+						logger.Debugw(ctx, "MibSync FSM - GetResponse Data for Onu-G - VendorId/SerialNumber", log.Fields{"device-id": oo.deviceID,
+							"onuDeviceEntry.vendorID": oo.SOnuPersistentData.PersVendorID, "onuDeviceEntry.serialNumber": oo.SOnuPersistentData.PersSerialNumber})
+					} else {
+						logger.Infow(ctx, "MibSync FSM - SerialNumber has wrong length - fill serialNumber with zeros", log.Fields{"device-id": oo.deviceID, "length": len(snBytes)})
+						oo.SOnuPersistentData.PersSerialNumber = cEmptySerialNumberString
+					}
+					oo.MutexPersOnuConfig.Unlock()
+				} else {
+					logger.Errorw(ctx, "MibSync FSM - mandatory attribute SerialNumber not present in OnuG instance - handling of MibSyncChan stopped!",
+						log.Fields{"device-id": oo.deviceID})
+					_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
+					return fmt.Errorf("mibSync FSM - mandatory attribute SerialNumber not present in OnuG instance - handling of MibSyncChan stopped: %s", oo.deviceID)
+				}
 				// trigger retrieval of EquipmentId
 				_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetEquipmentID)
 				return nil
 			case "Onu2G":
 				oo.mutexLastTxParamStruct.RUnlock()
+				var equipmentID string
+				if onu2GEquipmentID, ok := meAttributes[me.Onu2G_EquipmentId]; ok {
+					equipmentID = cmn.TrimStringFromMeOctet(onu2GEquipmentID)
+					if equipmentID == "" {
+						logger.Infow(ctx, "MibSync FSM - optional attribute EquipmentID is empty in Onu2G instance - fill with appropriate value", log.Fields{"device-id": oo.deviceID})
+						equipmentID = cEmptyEquipIDString
+					}
+				} else {
+					logger.Infow(ctx, "MibSync FSM - optional attribute EquipmentID not present in Onu2G instance - fill with appropriate value", log.Fields{"device-id": oo.deviceID})
+					equipmentID = cNotPresentEquipIDString
+				}
 				oo.MutexPersOnuConfig.Lock()
-				oo.SOnuPersistentData.PersEquipmentID = cmn.TrimStringFromMeOctet(meAttributes[me.Onu2G_EquipmentId])
+				oo.SOnuPersistentData.PersEquipmentID = equipmentID
 				logger.Debugw(ctx, "MibSync FSM - GetResponse Data for Onu2-G - EquipmentId", log.Fields{"device-id": oo.deviceID,
 					"onuDeviceEntry.equipmentID": oo.SOnuPersistentData.PersEquipmentID})
 				oo.MutexPersOnuConfig.Unlock()
+
 				// trigger retrieval of 1st SW-image info
 				_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetFirstSwVersion)
 				return nil
@@ -726,13 +759,16 @@
 						oo.deviceID, entityID)
 				}
 				// need to use function for go lint complexity
-				oo.HandleSwImageIndications(ctx, entityID, meAttributes)
+				if !oo.HandleSwImageIndications(ctx, entityID, meAttributes) {
+					logger.Errorw(ctx, "MibSync FSM - Not all mandatory attributes present in in SoftwareImage instance - handling of MibSyncChan stopped!", log.Fields{"device-id": oo.deviceID})
+					_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
+					return fmt.Errorf("mibSync FSM - Not all mandatory attributes present in in SoftwareImage instance - handling of MibSyncChan stopped: %s", oo.deviceID)
+				}
 				return nil
 			case "IpHostConfigData":
 				oo.mutexLastTxParamStruct.RUnlock()
-				ipHostConfigMacAddress, ok := meAttributes[me.IpHostConfigData_MacAddress]
 				oo.MutexPersOnuConfig.Lock()
-				if ok {
+				if ipHostConfigMacAddress, ok := meAttributes[me.IpHostConfigData_MacAddress]; ok {
 					macBytes, _ := me.InterfaceToOctets(ipHostConfigMacAddress)
 					if cmn.OmciMacAddressLen == len(macBytes) {
 						oo.SOnuPersistentData.PersMacAddress = hex.EncodeToString(macBytes[:])
@@ -743,7 +779,8 @@
 						oo.SOnuPersistentData.PersMacAddress = cEmptyMacAddrString
 					}
 				} else {
-					logger.Infow(ctx, "MibSync FSM - MacAddress field not present in ip host config - fill macAddress with zeros", log.Fields{"device-id": oo.deviceID})
+					// since ONU creates instances of this ME automatically only when IP host services are available, processing continues here despite the error
+					logger.Infow(ctx, "MibSync FSM - MacAddress attribute not present in IpHostConfigData instance - fill macAddress with zeros", log.Fields{"device-id": oo.deviceID})
 					oo.SOnuPersistentData.PersMacAddress = cEmptyMacAddrString
 				}
 				oo.MutexPersOnuConfig.Unlock()
@@ -752,7 +789,13 @@
 				return nil
 			case "OnuData":
 				oo.mutexLastTxParamStruct.RUnlock()
-				oo.checkMdsValue(ctx, meAttributes[me.OnuData_MibDataSync].(uint8))
+				if onuDataMibDataSync, ok := meAttributes[me.OnuData_MibDataSync]; ok {
+					oo.checkMdsValue(ctx, onuDataMibDataSync.(uint8))
+				} else {
+					logger.Errorw(ctx, "MibSync FSM - MibDataSync attribute not present in OnuData instance - handling of MibSyncChan stopped!", log.Fields{"device-id": oo.deviceID})
+					_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
+					return fmt.Errorf("mibSync FSM - VendorId attribute not present in OnuG instance - handling of MibSyncChan stopped: %s", oo.deviceID)
+				}
 				return nil
 			default:
 				oo.mutexLastTxParamStruct.RUnlock()
@@ -776,10 +819,26 @@
 }
 
 //HandleSwImageIndications updates onuSwImageIndications with the ONU data just received
-func (oo *OnuDeviceEntry) HandleSwImageIndications(ctx context.Context, entityID uint16, meAttributes me.AttributeValueMap) {
-	imageIsCommitted := meAttributes[me.SoftwareImage_IsCommitted].(uint8)
-	imageIsActive := meAttributes[me.SoftwareImage_IsActive].(uint8)
-	imageVersion := cmn.TrimStringFromMeOctet(meAttributes[me.SoftwareImage_Version])
+func (oo *OnuDeviceEntry) HandleSwImageIndications(ctx context.Context, entityID uint16, meAttributes me.AttributeValueMap) bool {
+
+	var imageVersion string
+	var imageIsCommitted, imageIsActive uint8
+
+	allMandAttribsPresent := false
+	if softwareImageIsCommitted, ok := meAttributes[me.SoftwareImage_IsCommitted]; ok {
+		if softwareImageIsActiveimage, ok := meAttributes[me.SoftwareImage_IsActive]; ok {
+			if softwareImageVersion, ok := meAttributes[me.SoftwareImage_Version]; ok {
+				imageVersion = cmn.TrimStringFromMeOctet(softwareImageVersion)
+				imageIsActive = softwareImageIsActiveimage.(uint8)
+				imageIsCommitted = softwareImageIsCommitted.(uint8)
+				allMandAttribsPresent = true
+			}
+		}
+	}
+	if !allMandAttribsPresent {
+		logger.Errorw(ctx, "MibSync FSM - Not all mandatory attributes present in SoftwareImage instance - skip processing!", log.Fields{"device-id": oo.deviceID})
+		return allMandAttribsPresent
+	}
 	oo.MutexPersOnuConfig.RLock()
 	logger.Infow(ctx, "MibSync FSM - GetResponse Data for SoftwareImage",
 		log.Fields{"device-id": oo.deviceID, "entityID": entityID,
@@ -809,7 +868,7 @@
 		}
 		oo.mutexOnuSwImageIndications.Unlock()
 		_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetSecondSwVersion)
-		return
+		return allMandAttribsPresent
 	} else if cmn.SecondSwImageMeID == entityID {
 		//2nd image info might conflict with first image info, in which case we priorize first image info!
 		oo.mutexOnuSwImageIndications.Lock()
@@ -847,8 +906,8 @@
 		}
 		oo.mutexOnuSwImageIndications.Unlock()
 		_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetMacAddress)
-		return
 	}
+	return allMandAttribsPresent
 }
 
 func (oo *OnuDeviceEntry) handleOmciMessage(ctx context.Context, msg cmn.OmciMessage) {
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
index bed9b77..9014283 100755
--- a/internal/pkg/mib/onu_device_entry.go
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -124,8 +124,11 @@
 	cSuffixMibTemplateKvStore   = "%s/%s/%s"
 )
 
+const cEmptyVendorIDString = "____"
 const cEmptyMacAddrString = "000000000000"
 const cEmptySerialNumberString = "0000000000000000"
+const cEmptyEquipIDString = "EMPTY_EQUIP_ID"
+const cNotPresentEquipIDString = "NOT_PRESENT_EQUIP_ID"
 
 type uniPersConfig struct {
 	PersUniID      uint8                   `json:"uni_id"`
diff --git a/internal/pkg/swupg/omci_onu_upgrade.go b/internal/pkg/swupg/omci_onu_upgrade.go
index 369890a..006c62c 100755
--- a/internal/pkg/swupg/omci_onu_upgrade.go
+++ b/internal/pkg/swupg/omci_onu_upgrade.go
@@ -1625,15 +1625,28 @@
 			log.Fields{"device-id": oFsm.deviceID})
 		return
 	}
-
 	meAttributes := msgObj.Attributes
-	imageIsCommitted := meAttributes[me.SoftwareImage_IsCommitted].(uint8)
-	imageIsActive := meAttributes[me.SoftwareImage_IsActive].(uint8)
-	imageVersion := cmn.TrimStringFromMeOctet(meAttributes[me.SoftwareImage_Version])
-	logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
-		log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
-			"version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
+	var imageVersion string
+	var imageIsCommitted, imageIsActive uint8
 
+	if softwareImageIsCommitted, ok := meAttributes[me.SoftwareImage_IsCommitted]; ok {
+		if softwareImageIsActiveimage, ok := meAttributes[me.SoftwareImage_IsActive]; ok {
+			if softwareImageVersion, ok := meAttributes[me.SoftwareImage_Version]; ok {
+				imageIsCommitted = softwareImageIsCommitted.(uint8)
+				imageIsActive = softwareImageIsActiveimage.(uint8)
+				imageVersion = cmn.TrimStringFromMeOctet(softwareImageVersion)
+				logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
+					log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
+						"version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
+			} else {
+				logger.Errorw(ctx,
+					"OnuUpgradeFsm - Not all mandatory attributes present in in SoftwareImage instance - handling stopped!",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false)
+				return
+			}
+		}
+	}
 	if oFsm.PAdaptFsm.PFsm.Current() == UpgradeStCheckImageName {
 		//image name check after EndSwDownload, this state (and block) can only be taken if APIVersion43 is used
 		oFsm.verifyOnuSwStatusAfterDownload(ctx, msgObj.EntityInstance, imageVersion, imageIsActive, imageIsCommitted)
diff --git a/internal/pkg/swupg/onu_image_status.go b/internal/pkg/swupg/onu_image_status.go
index 02d92bc..ae798d0 100755
--- a/internal/pkg/swupg/onu_image_status.go
+++ b/internal/pkg/swupg/onu_image_status.go
@@ -207,11 +207,14 @@
 
 	if _, ok := oo.requestedAttributes[me.SoftwareImage_Version]; ok {
 		if msgObj.Result != me.Success {
-			logger.Errorw(ctx, "processAttributesReceived retrieval of mandatory attributes failed",
+			logger.Errorw(ctx, "processAttributesReceived - retrieval of mandatory attributes not successful",
 				log.Fields{"device-id": oo.deviceID})
-			return fmt.Errorf("process-image-status-response-error")
+			return fmt.Errorf("retrieve-mandatory-attributes-not-successful")
 		}
-		oo.pDevEntry.HandleSwImageIndications(ctx, msgObj.EntityInstance, meAttributes)
+		if !oo.pDevEntry.HandleSwImageIndications(ctx, msgObj.EntityInstance, meAttributes) {
+			logger.Errorw(ctx, "processAttributesReceived - not all mandatory attributes present in SoftwareImage instance", log.Fields{"device-id": oo.deviceID})
+			return fmt.Errorf("not-all-mandatory-attributes-present")
+		}
 	}
 	for k := range oo.requestedAttributes {
 		switch k {
diff --git a/internal/pkg/uniprt/uniportstatus.go b/internal/pkg/uniprt/uniportstatus.go
index 4c294ce..749293a 100755
--- a/internal/pkg/uniprt/uniportstatus.go
+++ b/internal/pkg/uniprt/uniportstatus.go
@@ -32,6 +32,7 @@
 
 //UniPortStatus implements methods to get uni port status info
 type UniPortStatus struct {
+	deviceID          string
 	pDeviceHandler    cmn.IdeviceHandler
 	pOmiCC            *cmn.OmciCC
 	omciRespChn       chan cmn.Message
@@ -41,6 +42,7 @@
 //NewUniPortStatus creates a new instance of UniPortStatus
 func NewUniPortStatus(apDeviceHandler cmn.IdeviceHandler, apOmicc *cmn.OmciCC) *UniPortStatus {
 	return &UniPortStatus{
+		deviceID:       apDeviceHandler.GetDeviceID(),
 		pDeviceHandler: apDeviceHandler,
 		pOmiCC:         apOmicc,
 		omciRespChn:    make(chan cmn.Message),
@@ -71,7 +73,7 @@
 			}
 		}
 	}
-	logger.Errorw(ctx, "GetUniPortStatus uniIdx is not valid", log.Fields{"uniIdx": uniIdx})
+	logger.Errorw(ctx, "GetUniPortStatus uniIdx is not valid", log.Fields{"uniIdx": uniIdx, "device-id": portStatus.deviceID})
 	return PostUniStatusErrResponse(extension.GetValueResponse_INVALID_PORT_TYPE)
 }
 
@@ -80,10 +82,10 @@
 	select {
 	// maybe be also some outside cancel (but no context modeled for the moment ...)
 	case <-ctx.Done():
-		logger.Errorf(ctx, "waitforGetUniPortStatus Context done")
+		logger.Errorw(ctx, "waitforGetUniPortStatus Context done", log.Fields{"device-id": portStatus.deviceID})
 		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
 	case <-time.After(uniStatusTimeout * time.Second):
-		logger.Errorf(ctx, "waitforGetUniPortStatus  timeout")
+		logger.Errorw(ctx, "waitforGetUniPortStatus  timeout", log.Fields{"device-id": portStatus.deviceID})
 		return PostUniStatusErrResponse(extension.GetValueResponse_TIMEOUT)
 
 	case omciMsg := <-portStatus.omciRespChn:
@@ -98,23 +100,24 @@
 
 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})
+		"msg.OmciMsg.TransactionID": msg.OmciMsg.TransactionID, "DeviceIdentfier": msg.OmciMsg.DeviceIdentifier,
+		"device-id": portStatus.deviceID})
 
 	if msg.OmciMsg.MessageType != omci.GetResponseType {
 		logger.Debugw(ctx, "processGetUniStatusResp error", log.Fields{"incorrect RespType": msg.OmciMsg.MessageType,
-			"expected": omci.GetResponseType})
+			"expected": omci.GetResponseType, "device-id": portStatus.deviceID})
 		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
 	}
 
 	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
 	if msgLayer == nil {
-		logger.Errorf(ctx, "processGetUniStatusResp omci Msg layer not found - ")
+		logger.Errorw(ctx, "processGetUniStatusResp omci Msg layer not found", log.Fields{"device-id": portStatus.deviceID})
 		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
 
 	}
 	msgObj, msgOk := msgLayer.(*omci.GetResponse)
 	if !msgOk {
-		logger.Errorf(ctx, "processGetUniStatusResp omci msgObj layer could not be found ")
+		logger.Errorw(ctx, "processGetUniStatusResp omci msgObj layer could not be found", log.Fields{"device-id": portStatus.deviceID})
 		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
 
 	}
@@ -132,33 +135,53 @@
 			},
 		},
 	}
-	if meAttributes[me.PhysicalPathTerminationPointEthernetUni_OperationalState].(uint8) == 0 {
-		singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_ENABLED
-	} else if meAttributes[me.PhysicalPathTerminationPointEthernetUni_OperationalState].(uint8) == 1 {
-		singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_DISABLED
+	if pptpEthUniOperState, ok := meAttributes[me.PhysicalPathTerminationPointEthernetUni_OperationalState]; ok {
+		if pptpEthUniOperState.(uint8) == 0 {
+			singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_ENABLED
+		} else if pptpEthUniOperState.(uint8) == 1 {
+			singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_DISABLED
+		} else {
+			singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_OPERSTATE_UNDEFINED
+		}
 	} else {
+		logger.Infow(ctx, "processGetUniStatusResp - optional attribute pptpEthUniOperState not present!",
+			log.Fields{"device-id": portStatus.deviceID})
 		singleValResp.Response.GetUniInfo().OperState = extension.GetOnuUniInfoResponse_OPERSTATE_UNDEFINED
 	}
 
-	if meAttributes[me.PhysicalPathTerminationPointEthernetUni_AdministrativeState].(uint8) == 0 {
-		singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_UNLOCKED
-	} else if meAttributes[me.PhysicalPathTerminationPointEthernetUni_AdministrativeState].(uint8) == 1 {
-		singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_LOCKED
+	if pptpEthUniAdminState, ok := meAttributes[me.PhysicalPathTerminationPointEthernetUni_OperationalState]; ok {
+		if pptpEthUniAdminState.(uint8) == 0 {
+			singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_UNLOCKED
+		} else if pptpEthUniAdminState.(uint8) == 1 {
+			singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_LOCKED
+		} else {
+			singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_ADMSTATE_UNDEFINED
+		}
 	} else {
-		singleValResp.Response.GetUniInfo().AdmState = extension.GetOnuUniInfoResponse_ADMSTATE_UNDEFINED
+		logger.Errorw(ctx, "processGetUniStatusResp - mandatory attribute pptpEthUniAdminState not present!",
+			log.Fields{"device-id": portStatus.deviceID})
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
 	}
-	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,
+
+	if pptpEthUniConfigInd, ok := meAttributes[me.PhysicalPathTerminationPointEthernetUni_ConfigurationInd]; ok {
+		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 := pptpEthUniConfigInd.(uint8)
+		singleValResp.Response.GetUniInfo().ConfigInd = configIndMap[configInd]
+	} else {
+		logger.Errorw(ctx, "processGetUniStatusResp - mandatory attribute pptpEthUniConfigInd not present!",
+			log.Fields{"device-id": portStatus.deviceID})
+		return PostUniStatusErrResponse(extension.GetValueResponse_INTERNAL_ERROR)
 	}
-	configInd := meAttributes[me.PhysicalPathTerminationPointEthernetUni_ConfigurationInd].(uint8)
-	singleValResp.Response.GetUniInfo().ConfigInd = configIndMap[configInd]
+
 	return &singleValResp
 }