ONU SW upgrade API change - step 3: refinement of download and image status indications

Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: If78ac4b1e2e5c18042d538b1db1fd69945abc64f
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index fe64bf2..da6936f 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -1182,7 +1182,8 @@
 }
 
 //onuSwActivateRequest ensures activation of the requested image with commit options
-func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context, aVersion string, aCommitRequest bool) {
+func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
+	aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
 	var err error
 	//SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
 	//  1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
@@ -1191,7 +1192,7 @@
 	pDevEntry := dh.getOnuDeviceEntry(ctx, true)
 	if pDevEntry == nil {
 		logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
-		return
+		return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
 	}
 	dh.lockUpgradeFsm.RLock()
 	if dh.pOnuUpradeFsm != nil {
@@ -1200,21 +1201,27 @@
 			dh.deviceID, dh.deviceID)
 		if getErr != nil || onuVolthaDevice == nil {
 			logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
-			return
+			return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
 		}
 		//  use the OnuVendor identification from this device for the internal unique name
 		imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
 		// 1.) check a started upgrade process and rely the activation request to it
 		if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
+			//if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
 			logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
 				"device-id": dh.deviceID, "error": err})
-		} else {
-			logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
-				"device-id": dh.deviceID, "image-id": imageIdentifier})
+			return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
 		}
-		//if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
-		//   (even though parameter setting is not accepted)
-		return
+		logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
+			"device-id": dh.deviceID, "image-id": imageIdentifier})
+		var pImageStates *voltha.ImageState
+		if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
+			pImageStates = &voltha.ImageState{}
+			pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+			pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
+			pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
+		}
+		return pImageStates, nil
 	} //else
 	dh.lockUpgradeFsm.RUnlock()
 
@@ -1224,7 +1231,7 @@
 	if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
 		logger.Errorw(ctx, "get inactive image failed", log.Fields{
 			"device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
-		return
+		return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
 	}
 	err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
 	if err == nil {
@@ -1232,18 +1239,27 @@
 			inactiveImageID, aCommitRequest); err != nil {
 			logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
 				"device-id": dh.deviceID, "error": err})
-			return
+			return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
 		}
 		logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
 			"device-id": dh.deviceID, "image-version": aVersion})
-		return
+		var pImageStates *voltha.ImageState
+		if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
+			pImageStates := &voltha.ImageState{}
+			pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+			pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
+			pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
+		}
+		return pImageStates, nil
 	} //else
 	logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
 		"device-id": dh.deviceID, "error": err})
+	return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
 }
 
 //onuSwCommitRequest ensures commitment of the requested image
-func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context, aVersion string) {
+func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
+	aVersion string) (*voltha.ImageState, error) {
 	var err error
 	//SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
 	//  1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
@@ -1252,7 +1268,7 @@
 	pDevEntry := dh.getOnuDeviceEntry(ctx, true)
 	if pDevEntry == nil {
 		logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
-		return
+		return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
 	}
 	dh.lockUpgradeFsm.RLock()
 	if dh.pOnuUpradeFsm != nil {
@@ -1261,54 +1277,68 @@
 			dh.deviceID, dh.deviceID)
 		if getErr != nil || onuVolthaDevice == nil {
 			logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
-			return
+			return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
 		}
 		//  use the OnuVendor identification from this device for the internal unique name
 		imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
 		// 1.) check a started upgrade process and rely the commitment request to it
 		if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
+			//if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
 			logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
 				"device-id": dh.deviceID, "error": err})
-		} else {
-			logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
-				"device-id": dh.deviceID, "image-id": imageIdentifier})
+			return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
 		}
-		//if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
-		//   (even though parameter setting is not accepted)
-		return
+		logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
+			"device-id": dh.deviceID, "image-id": imageIdentifier})
+		var pImageStates *voltha.ImageState
+		if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
+			pImageStates := &voltha.ImageState{}
+			pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+			pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
+			pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
+		}
+		return pImageStates, nil
 	} //else
 	dh.lockUpgradeFsm.RUnlock()
 
-	// 2.) check if requested image-version equals the inactive one and start its commitment
+	// 2.) use the active image to directly commit
 	var activeImageID uint16
 	if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
 		logger.Errorw(ctx, "get active image failed", log.Fields{
 			"device-id": dh.deviceID, "err": err, "image-id": activeImageID})
-		return
+		return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
 	}
 	err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
 	if err == nil {
 		if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
 			logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
 				"device-id": dh.deviceID, "error": err})
-			return
+			return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
 		}
 		logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
 			"device-id": dh.deviceID, "image-version": aVersion})
-		return
+		var pImageStates *voltha.ImageState
+		if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
+			pImageStates := &voltha.ImageState{}
+			pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+			pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
+			pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
+		}
+		return pImageStates, nil
 	} //else
 	logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
 		"device-id": dh.deviceID, "error": err})
+	return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
 }
 
 func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
 	aVersion string, pDeviceImageState *voltha.DeviceImageState) {
 	pDeviceImageState.DeviceId = dh.deviceID
-	pDeviceImageState.ImageState.Version = aImageIdentifier
+	pDeviceImageState.ImageState.Version = aVersion
 	dh.lockUpgradeFsm.RLock()
 	if dh.pOnuUpradeFsm != nil {
 		dh.lockUpgradeFsm.RUnlock()
-		if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err != nil {
+		if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
 			pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
 			pDeviceImageState.ImageState.Reason = pImageStates.Reason
 			pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
@@ -2636,6 +2666,7 @@
 			// commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
 			//  (some manual forced commit could do without)
 			if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
+				// here no need to update the upgrade image state to activated as the state will be immediately be set to committing
 				if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
 					if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
 						logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
@@ -2649,6 +2680,16 @@
 					_ = pUpgradeStatemachine.Event(upgradeEvAbort)
 					return
 				}
+			} else {
+				//upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
+				// upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
+				if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
+					if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
+						logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
+							"state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
+						dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
+					}
+				}
 			}
 		}
 	} else {
diff --git a/internal/pkg/onuadaptercore/omci_onu_upgrade.go b/internal/pkg/onuadaptercore/omci_onu_upgrade.go
index 9d57c89..b21291f 100644
--- a/internal/pkg/onuadaptercore/omci_onu_upgrade.go
+++ b/internal/pkg/onuadaptercore/omci_onu_upgrade.go
@@ -60,6 +60,7 @@
 	upgradeEvContinueFinalize   = "upgradeEvContinueFinalize"
 	upgradeEvWaitForActivate    = "upgradeEvWaitForActivate"
 	upgradeEvRequestActivate    = "upgradeEvRequestActivate"
+	upgradeEvActivationDone     = "upgradeEvActivationDone"
 	upgradeEvWaitForCommit      = "upgradeEvWaitForCommit"
 	upgradeEvCommitSw           = "upgradeEvCommitSw"
 	upgradeEvCheckCommitted     = "upgradeEvCheckCommitted"
@@ -83,6 +84,7 @@
 	upgradeStWaitEndDL          = "upgradeStWaitEndDL"
 	upgradeStWaitForActivate    = "upgradeStWaitForActivate"
 	upgradeStRequestingActivate = "upgradeStRequestingActivate"
+	upgradeStActivated          = "upgradeStActivated"
 	upgradeStWaitForCommit      = "upgradeStWaitForCommit"
 	upgradeStCommitSw           = "upgradeStCommitSw"
 	upgradeStCheckCommitted     = "upgradeStCheckCommitted"
@@ -187,8 +189,9 @@
 			{Name: upgradeEvWaitForActivate, Src: []string{upgradeStWaitEndDL}, Dst: upgradeStWaitForActivate},
 			{Name: upgradeEvRequestActivate, Src: []string{upgradeStStarting, upgradeStWaitEndDL, upgradeStWaitForActivate},
 				Dst: upgradeStRequestingActivate}, //allows also for direct activation (without download) [TODO!!!]
+			{Name: upgradeEvActivationDone, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStActivated},
 			{Name: upgradeEvWaitForCommit, Src: []string{upgradeStRequestingActivate}, Dst: upgradeStWaitForCommit},
-			{Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit},
+			{Name: upgradeEvCommitSw, Src: []string{upgradeStStarting, upgradeStWaitForCommit, upgradeStActivated},
 				Dst: upgradeStCommitSw}, //allows also for direct commitment (without download) [TODO!!!]
 			{Name: upgradeEvCheckCommitted, Src: []string{upgradeStCommitSw}, Dst: upgradeStCheckCommitted},
 
@@ -199,13 +202,14 @@
 					upgradeStCreatingGemNCTPs, upgradeStCreatingGemIWs, upgradeStSettingPQs}, Dst: upgradeStStarting},
 			*/
 			// exceptional treatments
+			//on upgradeEvReset: upgradeStWaitForCommit and upgradeStActivated are not reset (to let the FSM survive the expected OnuDown indication)
 			{Name: upgradeEvReset, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
 				upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
-				upgradeStRequestingActivate, upgradeStCommitSw, upgradeStCheckCommitted}, //upgradeStWaitForCommit is not reset (later perhaps also not upgradeStWaitActivate)
+				upgradeStRequestingActivate, upgradeStCommitSw, upgradeStCheckCommitted},
 				Dst: upgradeStResetting},
 			{Name: upgradeEvAbort, Src: []string{upgradeStStarting, upgradeStWaitingAdapterDL, upgradeStPreparingDL, upgradeStDLSection,
 				upgradeStVerifyWindow, upgradeStDLSection, upgradeStFinalizeDL, upgradeStWaitEndDL, upgradeStWaitForActivate,
-				upgradeStRequestingActivate, upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
+				upgradeStRequestingActivate, upgradeStActivated, upgradeStWaitForCommit, upgradeStCommitSw, upgradeStCheckCommitted},
 				Dst: upgradeStResetting},
 			{Name: upgradeEvRestart, Src: []string{upgradeStResetting}, Dst: upgradeStDisabled},
 		},
@@ -346,6 +350,7 @@
 		oFsm.imageVersion = aImageVersion
 		oFsm.activateImage = true
 		oFsm.commitImage = aCommit
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN // this is just an activate request without prior download
 		oFsm.mutexUpgradeParams.Unlock()
 		//directly request the FSM to activate the image
 		_ = pBaseFsm.Event(upgradeEvRequestActivate) //no need to call the FSM event in background here
@@ -379,10 +384,10 @@
 		pBaseFsm = oFsm.pAdaptFsm.pFsm
 	}
 	if pBaseFsm != nil {
-		if pBaseFsm.Is(upgradeStWaitForCommit) {
-			logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for commit", log.Fields{"device-id": oFsm.deviceID})
-			_ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
-		}
+		//let the FSM decide if it is ready to process the event
+		logger.Debugw(ctx, "OnuUpgradeFsm requesting commit",
+			log.Fields{"device-id": oFsm.deviceID, "current FsmState": pBaseFsm.Current()})
+		_ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
 		return nil
 	}
 	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
@@ -405,6 +410,7 @@
 		oFsm.inactiveImageMeID = aActiveImageID //upgrade state machines inactive ImageId is the new active ImageId
 		oFsm.imageVersion = aImageVersion
 		oFsm.commitImage = true
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN // this is just a commit request without prior download
 		oFsm.mutexUpgradeParams.Unlock()
 		//directly request the FSM to activate the image
 		_ = pBaseFsm.Event(upgradeEvCommitSw) //no need to call the FSM event in background here
@@ -435,6 +441,13 @@
 	return pImageState, nil
 }
 
+//SetImageState sets the FSM internal volthaImageState
+func (oFsm *OnuUpgradeFsm) SetImageState(ctx context.Context, aImageState voltha.ImageState_ImageActivationState) {
+	oFsm.mutexUpgradeParams.Lock()
+	defer oFsm.mutexUpgradeParams.Unlock()
+	oFsm.volthaImageState = aImageState
+}
+
 //CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
 func (oFsm *OnuUpgradeFsm) CancelProcessing(ctx context.Context) {
 	//mutex protection is required for possible concurrent access to FSM members
@@ -847,7 +860,7 @@
 		pOnuUpgradeFsm := oFsm.pAdaptFsm
 		if pOnuUpgradeFsm != nil {
 			go func(a_pAFsm *AdapterFsm) {
-				_ = a_pAFsm.pFsm.Event(upgradeEvReset)
+				_ = a_pAFsm.pFsm.Event(upgradeEvAbort)
 			}(pOnuUpgradeFsm)
 		}
 		return
@@ -1111,9 +1124,11 @@
 				_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
 				return
 			}
-			oFsm.mutexUpgradeParams.RLock()
+			oFsm.mutexUpgradeParams.Lock()
 			if msgObj.EntityInstance == oFsm.inactiveImageMeID {
-				oFsm.mutexUpgradeParams.RUnlock()
+				oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
+				oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
+				oFsm.mutexUpgradeParams.Unlock()
 				logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
 				oFsm.mutexIsAwaitingOnuDlResponse.RLock()
 				if oFsm.isWaitingForOnuDlResponse {
@@ -1126,7 +1141,7 @@
 				oFsm.chReceiveExpectedResponse <- true //let the FSM proceed from the waitState
 				return
 			}
-			oFsm.mutexUpgradeParams.RUnlock()
+			oFsm.mutexUpgradeParams.Unlock()
 			logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
 				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
 			// TODO!!!: possibly repeat the end request (once)? or verify ONU upgrade state?
@@ -1162,14 +1177,19 @@
 				_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
 				return
 			}
-			oFsm.mutexUpgradeParams.RLock()
+			oFsm.mutexUpgradeParams.Lock()
 			if msgObj.EntityInstance == oFsm.inactiveImageMeID {
-				oFsm.mutexUpgradeParams.RUnlock()
-				logger.Infow(ctx, "Expected ActivateSwResponse received", log.Fields{"device-id": oFsm.deviceID})
-				_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
+				oFsm.mutexUpgradeParams.Unlock()
+				logger.Infow(ctx, "Expected ActivateSwResponse received",
+					log.Fields{"device-id": oFsm.deviceID, "commit": oFsm.commitImage})
+				if oFsm.commitImage {
+					_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvWaitForCommit)
+				} else {
+					_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvActivationDone) // let the FSM wait for external commit request
+				}
 				return
 			}
-			oFsm.mutexUpgradeParams.RUnlock()
+			oFsm.mutexUpgradeParams.Unlock()
 			logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
 				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
 			// TODO!!!: error treatment?
@@ -1283,15 +1303,13 @@
 					logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU",
 						log.Fields{"device-id": oFsm.deviceID})
 				}
-				oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVE
 				if imageIsCommitted == swIsCommitted {
-					oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
 					oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTED
 					logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
 					oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent)) //to let the handler now about success
 					oFsm.mutexUpgradeParams.Unlock()
 					//releasing the upgrade FSM
-					_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
+					_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
 					return
 				}
 				oFsm.mutexUpgradeParams.Unlock()
@@ -1334,7 +1352,7 @@
 		//the upgrade process has to be aborted
 		pUpgradeFsm := oFsm.pAdaptFsm
 		if pUpgradeFsm != nil {
-			_ = pUpgradeFsm.pFsm.Event(upgradeEvReset)
+			_ = pUpgradeFsm.pFsm.Event(upgradeEvAbort)
 		} else {
 			logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
 		}
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
index d8eb410..1c46457 100644
--- a/internal/pkg/onuadaptercore/openonu.go
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -852,7 +852,6 @@
 			loImageState := voltha.ImageState{}
 			loDeviceImageState.ImageState = &loImageState
 			loDeviceImageState.ImageState.Version = imageIdentifier
-			loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
 			//compared to download procedure the vendorID (from device) is secondary here
 			//   and only needed in case the upgrade process is based on some ongoing download process (and can be retrieved in deviceHandler if needed)
 			// start image activation activity for each possible device
@@ -863,12 +862,19 @@
 				//onu activation handling called in background without immediate error evaluation here
 				//  as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
 				//  state/progress/success of the request has to be verified using the Get_onu_image_status() API
-				go handler.onuSwActivateRequest(ctx, imageIdentifier, (*in).CommitOnSuccess)
-				loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
-				loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATING
+				if pImageStates, err := handler.onuSwActivateRequest(ctx, imageIdentifier, (*in).CommitOnSuccess); err != nil {
+					loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+					loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
+					loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
+				} else {
+					loDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
+					loDeviceImageState.ImageState.Reason = pImageStates.Reason
+					loDeviceImageState.ImageState.ImageState = pImageStates.ImageState
+				}
 			} else {
 				//cannot start SW activation for requested device
 				logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": loDeviceID})
+				loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
 				loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
 				loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
 			}
@@ -894,7 +900,6 @@
 			loImageState := voltha.ImageState{}
 			loDeviceImageState.ImageState = &loImageState
 			loDeviceImageState.ImageState.Version = imageIdentifier
-			loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
 			//compared to download procedure the vendorID (from device) is secondary here
 			//   and only needed in case the upgrade process is based on some ongoing download process (and can be retrieved in deviceHandler if needed)
 			// start image activation activity for each possible device
@@ -905,12 +910,19 @@
 				//onu commitment handling called in background without immediate error evaluation here
 				//  as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
 				//  state/progress/success of the request has to be verified using the Get_onu_image_status() API
-				go handler.onuSwCommitRequest(ctx, imageIdentifier)
-				loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
-				loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTING
+				if pImageStates, err := handler.onuSwCommitRequest(ctx, imageIdentifier); err != nil {
+					loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+					loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
+					loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
+				} else {
+					loDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
+					loDeviceImageState.ImageState.Reason = pImageStates.Reason
+					loDeviceImageState.ImageState.ImageState = pImageStates.ImageState
+				}
 			} else {
 				//cannot start SW commitment for requested device
 				logger.Warnw(ctx, "no handler found for image commitment", log.Fields{"device-id": loDeviceID})
+				loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
 				loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
 				loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
 			}