ONU SW upgrade API change - step 1 to allow for straightforward upgrade (with activate/commit options)
Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: I6808f8f41db40faa060ed7198025abdda8506ae7
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 07fa67b..fc29ac2 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -1100,6 +1100,182 @@
return err
}
+//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
+// after the OnuImage has been downloaded to the adapter, called in background
+func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
+ apDownloadManager *fileDownloadManager, aImageIdentifier string) {
+
+ var err error
+ pDevEntry := dh.getOnuDeviceEntry(ctx, true)
+ if pDevEntry == nil {
+ logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
+ return
+ }
+
+ var inactiveImageID uint16
+ if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
+ logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
+ "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
+ dh.lockUpgradeFsm.Lock()
+ defer dh.lockUpgradeFsm.Unlock()
+ if dh.pOnuUpradeFsm == nil {
+ //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
+ // but none yet defined
+ err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
+ if err == nil {
+ if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
+ apImageRequest, apDownloadManager, aImageIdentifier, dh.pOpenOnuAc.dlToOnuTimeout4M); err != nil {
+ logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
+ "device-id": dh.deviceID, "error": err})
+ return
+ }
+ } else {
+ logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
+ "device-id": dh.deviceID, "error": err})
+ }
+ return
+ }
+ //OnuSw upgrade already running - restart (with possible abort of running)
+ logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
+ pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
+ if pUpgradeStatemachine != nil {
+ if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
+ logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
+ "device-id": dh.deviceID, "error": err})
+ return
+ }
+ //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
+ // for now a second start of download should work again - must still be initiated by user
+ } else { //should never occur
+ logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
+ "device-id": dh.deviceID})
+ }
+ return
+ }
+ logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
+ "device-id": dh.deviceID, "error": err})
+}
+
+//onuSwActivateRequest ensures activation of the requested image with commit options
+func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context, aVersion string, aCommitRequest bool) {
+ 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)
+ // 2.) activation of the inactive image
+
+ 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
+ }
+ dh.lockUpgradeFsm.RLock()
+ if dh.pOnuUpradeFsm != nil {
+ dh.lockUpgradeFsm.RUnlock()
+ onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
+ 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
+ }
+ // 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 {
+ 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})
+ }
+ //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
+ } //else
+ dh.lockUpgradeFsm.RUnlock()
+
+ // 2.) check if requested image-version equals the inactive one and start its activation
+ // (image version is not [yet] checked - would be possible, but with increased effort ...)
+ var inactiveImageID uint16
+ 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
+ }
+ err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
+ if err == nil {
+ if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
+ 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
+ }
+ logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
+ "device-id": dh.deviceID, "image-version": aVersion})
+ return
+ } //else
+ logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
+ "device-id": dh.deviceID, "error": err})
+}
+
+//onuSwCommitRequest ensures commitment of the requested image
+func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context, aVersion string) {
+ 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)
+ // 2.) commitment of the active image
+
+ 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
+ }
+ dh.lockUpgradeFsm.RLock()
+ if dh.pOnuUpradeFsm != nil {
+ dh.lockUpgradeFsm.RUnlock()
+ onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
+ 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
+ }
+ // 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 {
+ 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})
+ }
+ //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
+ } //else
+ dh.lockUpgradeFsm.RUnlock()
+
+ // 2.) check if requested image-version equals the inactive one and start its commitment
+ 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
+ }
+ 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
+ }
+ logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
+ "device-id": dh.deviceID, "image-version": aVersion})
+ return
+ } //else
+ logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
+ "device-id": dh.deviceID, "error": err})
+}
+
// deviceHandler methods that implement the adapters interface requests## end #########
// #####################################################################################
@@ -1731,18 +1907,10 @@
}
//reset a possibly running upgrade FSM
- // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
- // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
+ // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
dh.lockUpgradeFsm.RLock()
if dh.pOnuUpradeFsm != nil {
- pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
- if pUpgradeStatemachine != nil {
- if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
- dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
- }
- _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
- }
- //else the FSM seems already to be in some released state
+ dh.pOnuUpradeFsm.CancelProcessing(ctx)
}
dh.lockUpgradeFsm.RUnlock()