[VOL-4506] ONU model not set correctly by openonu adapter

Change-Id: I29289883ae8bc596a5610a9a617f76a7778dba82
diff --git a/VERSION b/VERSION
index 530cdd9..139db26 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.4
+2.2.5-dev286
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 03b6ab3..641bd28 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -2357,10 +2357,25 @@
 
 func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
 	logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
-	//initiate DevStateUpdate
+	pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
+	if pDevEntry == nil {
+		logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
+		return
+	}
 	if !dh.IsReconciling() {
-		logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
+		logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
 			"OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
+		// update device info in core
+		pDevEntry.MutexPersOnuConfig.RLock()
+		dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
+		dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
+		dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
+		pDevEntry.MutexPersOnuConfig.RUnlock()
+		dh.logicalDeviceID = dh.DeviceID
+		if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
+			logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
+		}
+		// update device state in core
 		//we allow a possible OnuSw image commit only in the normal startup, not at reconciling
 		// in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
 		// maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
@@ -2376,7 +2391,7 @@
 			logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
 		}
 	} else {
-		logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
+		logger.Debugw(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
 			log.Fields{"device-id": dh.DeviceID})
 	}
 	_ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
@@ -2411,11 +2426,6 @@
 
 	dh.SetReadyForOmciConfig(true)
 
-	pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
-	if pDevEntry == nil {
-		logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
-		return
-	}
 	pDevEntry.MutexPersOnuConfig.RLock()
 	if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
 		pDevEntry.MutexPersOnuConfig.RUnlock()
@@ -2834,12 +2844,11 @@
 	eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
 	if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
 		deviceEntry.MutexPersOnuConfig.RLock()
+		eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
+		eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
 		eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
 		deviceEntry.MutexPersOnuConfig.RUnlock()
 		eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
-		deviceEntry.MutexPersOnuConfig.RLock()
-		eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
-		deviceEntry.MutexPersOnuConfig.RUnlock()
 		eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
 		logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
 			log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
diff --git a/internal/pkg/mib/mib_sync.go b/internal/pkg/mib/mib_sync.go
index 9c18f65..1cbe2a3 100755
--- a/internal/pkg/mib/mib_sync.go
+++ b/internal/pkg/mib/mib_sync.go
@@ -141,6 +141,30 @@
 	oo.mutexLastTxParamStruct.Unlock()
 }
 
+func (oo *OnuDeviceEntry) enterGettingVersionState(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "MibSync FSM", log.Fields{"Start getting Version in State": e.FSM.Current(), "device-id": oo.deviceID})
+	requestedAttributes := me.AttributeValueMap{me.OnuG_Version: ""}
+	oo.mutexLastTxParamStruct.Lock()
+	meInstance, err := oo.PDevOmciCC.SendGetMe(log.WithSpanFromContext(context.TODO(), ctx), me.OnuGClassID, cmn.OnugMeID,
+		requestedAttributes, oo.baseDeviceHandler.GetOmciTimeout(), true, oo.PMibUploadFsm.CommChan)
+	//accept also nil as (error) return value for writing to LastTx
+	//  - this avoids misinterpretation of new received OMCI messages
+	if err != nil {
+		oo.mutexLastTxParamStruct.Unlock()
+		logger.Errorw(ctx, "ONU-G get failed, aborting MibSync FSM", log.Fields{"device-id": oo.deviceID})
+		pMibUlFsm := oo.PMibUploadFsm
+		if pMibUlFsm != nil {
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
+			}(pMibUlFsm)
+		}
+		return
+	}
+	oo.lastTxParamStruct.lastTxMessageType = omci.GetRequestType
+	oo.lastTxParamStruct.pLastTxMeInstance = meInstance
+	oo.mutexLastTxParamStruct.Unlock()
+}
+
 func (oo *OnuDeviceEntry) enterGettingEquipIDAndOmccVersState(ctx context.Context, e *fsm.Event) {
 	logger.Debugw(ctx, "MibSync FSM", log.Fields{"Start getting EquipmentId and OMCC version in State": e.FSM.Current(), "device-id": oo.deviceID})
 	requestedAttributes := me.AttributeValueMap{me.Onu2G_EquipmentId: "", me.Onu2G_OpticalNetworkUnitManagementAndControlChannelOmccVersion: 0}
@@ -769,13 +793,15 @@
 	oo.mutexLastTxParamStruct.RUnlock()
 	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
 	if msgLayer == nil {
-		logger.Errorw(ctx, "omci Msg layer could not be detected for GetResponse - handling of MibSyncChan stopped", log.Fields{"device-id": oo.deviceID})
+		logger.Errorw(ctx, "omci Msg layer could not be detected for GetResponse - handling of MibSyncChan stopped",
+			log.Fields{"device-id": oo.deviceID})
 		_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
 		return fmt.Errorf("omci Msg layer could not be detected for GetResponse - handling of MibSyncChan stopped: %s", oo.deviceID)
 	}
 	msgObj, msgOk := msgLayer.(*omci.GetResponse)
 	if !msgOk {
-		logger.Errorw(ctx, "omci Msg layer could not be assigned for GetResponse - handling of MibSyncChan stopped", log.Fields{"device-id": oo.deviceID})
+		logger.Errorw(ctx, "omci Msg layer could not be assigned for GetResponse - handling of MibSyncChan stopped",
+			log.Fields{"device-id": oo.deviceID})
 		_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
 		return fmt.Errorf("omci Msg layer could not be assigned for GetResponse - handling of MibSyncChan stopped: %s", oo.deviceID)
 	}
@@ -786,59 +812,27 @@
 		if msgObj.EntityClass == oo.lastTxParamStruct.pLastTxMeInstance.GetClassID() && msgObj.EntityInstance == entityID {
 			meAttributes := msgObj.Attributes
 			meInstance := oo.lastTxParamStruct.pLastTxMeInstance.GetName()
-			logger.Debugf(ctx, "MibSync FSM - GetResponse Data for %s", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj}, meInstance)
+			logger.Debugf(ctx, "MibSync FSM - GetResponse Data for %s",
+				log.Fields{"device-id": oo.deviceID, "data-fields": msgObj}, meInstance)
 			switch meInstance {
 			case "OnuG":
 				oo.mutexLastTxParamStruct.RUnlock()
-				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.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)
-				}
-				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(UlEvGetEquipIDAndOmcc)
-				return nil
+				return oo.handleOmciGetResponseOnuG(ctx, meAttributes)
 			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})
+						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})
+					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()
@@ -862,10 +856,13 @@
 						"omccVersion": omccVersion, "isExtOmciSupported": oo.SOnuPersistentData.PersIsExtOmciSupported})
 					oo.MutexPersOnuConfig.Unlock()
 				} else {
-					logger.Errorw(ctx, "MibSync FSM - mandatory attribute OMCC version not present in Onu2G instance - handling of MibSyncChan stopped!",
+					logger.Errorw(ctx,
+						"MibSync FSM - mandatory attribute OMCC version not present in Onu2G instance - handling of MibSyncChan stopped!",
 						log.Fields{"device-id": oo.deviceID})
 					_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
-					return fmt.Errorf("mibSync FSM - mandatory attribute OMCC version not present in Onu2G instance - handling of MibSyncChan stopped: %s", oo.deviceID)
+					return fmt.Errorf(
+						"mibSync FSM - mandatory attribute OMCC version not present in Onu2G instance - handling of MibSyncChan stopped: %s",
+						oo.deviceID)
 				}
 				oo.MutexPersOnuConfig.RLock()
 				if oo.SOnuPersistentData.PersIsExtOmciSupported {
@@ -888,9 +885,13 @@
 				}
 				// need to use function for go lint complexity
 				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})
+					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 fmt.Errorf(
+						"mibSync FSM - Not all mandatory attributes present in in SoftwareImage instance - handling of MibSyncChan stopped: %s",
+						oo.deviceID)
 				}
 				return nil
 			case "IpHostConfigData":
@@ -903,12 +904,15 @@
 						logger.Debugw(ctx, "MibSync FSM - GetResponse Data for IpHostConfigData - MacAddress", log.Fields{"device-id": oo.deviceID,
 							"macAddress": oo.SOnuPersistentData.PersMacAddress})
 					} else {
-						logger.Infow(ctx, "MibSync FSM - MacAddress wrong length - fill macAddress with zeros", log.Fields{"device-id": oo.deviceID, "length": len(macBytes)})
+						logger.Infow(ctx, "MibSync FSM - MacAddress wrong length - fill macAddress with zeros",
+							log.Fields{"device-id": oo.deviceID, "length": len(macBytes)})
 						oo.SOnuPersistentData.PersMacAddress = cEmptyMacAddrString
 					}
 				} else {
-					// 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})
+					// 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()
@@ -920,9 +924,11 @@
 				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})
+					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 fmt.Errorf("mibSync FSM - VendorId attribute not present in OnuG instance - handling of MibSyncChan stopped: %s",
+						oo.deviceID)
 				}
 				return nil
 			default:
@@ -1062,6 +1068,95 @@
 	}
 }
 
+func (oo *OnuDeviceEntry) handleOmciGetResponseOnuG(ctx context.Context, meAttributes me.AttributeValueMap) error {
+	currentState := oo.PMibUploadFsm.PFsm.Current()
+	if currentState == UlStGettingVendorAndSerial {
+		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.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)
+		}
+		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
+			} 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)
+		}
+		oo.MutexPersOnuConfig.Lock()
+		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})
+		oo.MutexPersOnuConfig.Unlock()
+		// trigger retrieval of Version
+		_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetVersion)
+		return nil
+	} else if currentState == UlStGettingVersion {
+		if onuGVersion, ok := meAttributes[me.OnuG_Version]; ok {
+			version := cmn.TrimStringFromMeOctet(onuGVersion)
+			if version == "" {
+				logger.Infow(ctx, "MibSync FSM - mandatory attribute Version is empty in OnuG instance - fill with appropriate value",
+					log.Fields{"device-id": oo.deviceID})
+				version = cEmptyVersionString
+			}
+			oo.MutexPersOnuConfig.Lock()
+			oo.SOnuPersistentData.PersVersion = version
+			oo.MutexPersOnuConfig.Unlock()
+		} else {
+			logger.Errorw(ctx,
+				"MibSync FSM - mandatory attribute Version 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 Version not present in OnuG instance - handling of MibSyncChan stopped: %s",
+				oo.deviceID)
+		}
+		oo.MutexPersOnuConfig.Lock()
+		logger.Debugw(ctx, "MibSync FSM - GetResponse Data for Onu-G - Version", log.Fields{"device-id": oo.deviceID,
+			"onuDeviceEntry.version": oo.SOnuPersistentData.PersVersion})
+		oo.MutexPersOnuConfig.Unlock()
+		// trigger retrieval of EquipmentId and OMCC version
+		_ = oo.PMibUploadFsm.PFsm.Event(UlEvGetEquipIDAndOmcc)
+		return nil
+	} else {
+		logger.Errorw(ctx, "MibSync FSM - wrong state OnuG response processing - handling of MibSyncChan stopped!",
+			log.Fields{"currentState": currentState, "device-id": oo.deviceID})
+		_ = oo.PMibUploadFsm.PFsm.Event(UlEvStop)
+		return fmt.Errorf("mibSync FSM - wrong state OnuG response processing - handling of MibSyncChan stopped: %s",
+			oo.deviceID)
+	}
+}
+
 func (oo *OnuDeviceEntry) handleOmciGetResponseErrors(ctx context.Context, msgObj *omci.GetResponse) error {
 	var err error = nil
 	logger.Debugf(ctx, "MibSync FSM - erroneous result in GetResponse Data: %s", log.Fields{"device-id": oo.deviceID, "data-fields": msgObj}, msgObj.Result)
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
index 5dc3e50..2ebad75 100755
--- a/internal/pkg/mib/onu_device_entry.go
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -48,6 +48,7 @@
 	UlEvStart              = "UlEvStart"
 	UlEvResetMib           = "UlEvResetMib"
 	UlEvGetVendorAndSerial = "UlEvGetVendorAndSerial"
+	UlEvGetVersion         = "UlEvGetVersion"
 	UlEvGetEquipIDAndOmcc  = "UlEvGetEquipIDAndOmcc"
 	UlEvTestExtOmciSupport = "UlEvTestExtOmciSupport"
 	UlEvGetFirstSwVersion  = "UlEvGetFirstSwVersion"
@@ -72,6 +73,7 @@
 	UlStStarting               = "UlStStarting"
 	UlStResettingMib           = "UlStResettingMib"
 	UlStGettingVendorAndSerial = "UlStGettingVendorAndSerial"
+	UlStGettingVersion         = "UlStGettingVersion"
 	UlStGettingEquipIDAndOmcc  = "UlStGettingEquipIDAndOmcc"
 	UlStTestingExtOmciSupport  = "UlStTestingExtOmciSupport"
 	UlStGettingFirstSwVersion  = "UlStGettingFirstSwVersion"
@@ -127,6 +129,7 @@
 )
 
 const cEmptyVendorIDString = "____"
+const cEmptyVersionString = "______________"
 const cEmptyMacAddrString = "000000000000"
 const cEmptySerialNumberString = "0000000000000000"
 const cEmptyEquipIDString = "EMPTY_EQUIP_ID"
@@ -144,6 +147,7 @@
 	PersSerialNumber       string            `json:"serial_number"`
 	PersMacAddress         string            `json:"mac_address"`
 	PersVendorID           string            `json:"vendor_id"`
+	PersVersion            string            `json:"version"`
 	PersEquipmentID        string            `json:"equipment_id"`
 	PersIsExtOmciSupported bool              `json:"is_ext_omci_supported"`
 	PersActiveSwVersion    string            `json:"active_sw_version"`
@@ -295,7 +299,8 @@
 
 			{Name: UlEvResetMib, Src: []string{UlStStarting}, Dst: UlStResettingMib},
 			{Name: UlEvGetVendorAndSerial, Src: []string{UlStResettingMib}, Dst: UlStGettingVendorAndSerial},
-			{Name: UlEvGetEquipIDAndOmcc, Src: []string{UlStGettingVendorAndSerial}, Dst: UlStGettingEquipIDAndOmcc},
+			{Name: UlEvGetVersion, Src: []string{UlStGettingVendorAndSerial}, Dst: UlStGettingVersion},
+			{Name: UlEvGetEquipIDAndOmcc, Src: []string{UlStGettingVersion}, Dst: UlStGettingEquipIDAndOmcc},
 			{Name: UlEvTestExtOmciSupport, Src: []string{UlStGettingEquipIDAndOmcc}, Dst: UlStTestingExtOmciSupport},
 			{Name: UlEvGetFirstSwVersion, Src: []string{UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport}, Dst: UlStGettingFirstSwVersion},
 			{Name: UlEvGetSecondSwVersion, Src: []string{UlStGettingFirstSwVersion}, Dst: UlStGettingSecondSwVersion},
@@ -337,11 +342,11 @@
 			{Name: UlEvSuccess, Src: []string{UlStResynchronizing}, Dst: UlStInSync},
 			{Name: UlEvDiffsFound, Src: []string{UlStResynchronizing}, Dst: UlStOutOfSync},
 
-			{Name: UlEvTimeout, Src: []string{UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport,
+			{Name: UlEvTimeout, Src: []string{UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingVersion, UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport,
 				UlStGettingFirstSwVersion, UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing,
 				UlStVerifyingAndStoringTPs, UlStExaminingMds, UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStStarting},
 
-			{Name: UlEvStop, Src: []string{UlStStarting, UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport,
+			{Name: UlEvStop, Src: []string{UlStStarting, UlStResettingMib, UlStGettingVendorAndSerial, UlStGettingVersion, UlStGettingEquipIDAndOmcc, UlStTestingExtOmciSupport,
 				UlStGettingFirstSwVersion, UlStGettingSecondSwVersion, UlStGettingMacAddress, UlStGettingMibTemplate, UlStUploading, UlStResynchronizing,
 				UlStVerifyingAndStoringTPs, UlStExaminingMds, UlStUploadDone, UlStInSync, UlStOutOfSync, UlStAuditing, UlStReAuditing}, Dst: UlStDisabled},
 		},
@@ -351,6 +356,7 @@
 			"enter_" + UlStStarting:               func(e *fsm.Event) { onuDeviceEntry.enterStartingState(ctx, e) },
 			"enter_" + UlStResettingMib:           func(e *fsm.Event) { onuDeviceEntry.enterResettingMibState(ctx, e) },
 			"enter_" + UlStGettingVendorAndSerial: func(e *fsm.Event) { onuDeviceEntry.enterGettingVendorAndSerialState(ctx, e) },
+			"enter_" + UlStGettingVersion:         func(e *fsm.Event) { onuDeviceEntry.enterGettingVersionState(ctx, e) },
 			"enter_" + UlStGettingEquipIDAndOmcc:  func(e *fsm.Event) { onuDeviceEntry.enterGettingEquipIDAndOmccVersState(ctx, e) },
 			"enter_" + UlStTestingExtOmciSupport:  func(e *fsm.Event) { onuDeviceEntry.enterTestingExtOmciSupportState(ctx, e) },
 			"enter_" + UlStGettingFirstSwVersion:  func(e *fsm.Event) { onuDeviceEntry.enterGettingFirstSwVersionState(ctx, e) },
@@ -538,7 +544,7 @@
 	oo.MutexPersOnuConfig.Lock()
 	defer oo.MutexPersOnuConfig.Unlock()
 	oo.SOnuPersistentData =
-		onuPersistentData{0, 0, "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
+		onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
 	oo.mutexOnuKVStore.RLock()
 	Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
 	oo.mutexOnuKVStore.RUnlock()
@@ -593,7 +599,7 @@
 
 	oo.SOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector default entry
 	oo.SOnuPersistentData =
-		onuPersistentData{0, 0, "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
+		onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
 	logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
 	oo.mutexOnuKVStore.Lock()
 	err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)