diff --git a/internal/pkg/swupg/adapter_download_manager.go b/internal/pkg/swupg/adapter_download_manager.go
new file mode 100755
index 0000000..64f5324
--- /dev/null
+++ b/internal/pkg/swupg/adapter_download_manager.go
@@ -0,0 +1,290 @@
+/*
+ * 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 swupg provides the utilities for onu sw upgrade
+package swupg
+
+import (
+	"bufio"
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"os"
+	"path/filepath"
+	"sync"
+	"time"
+
+	"github.com/opencord/voltha-protos/v5/go/voltha"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+// ### downloadToAdapter related definitions  ####
+
+//not yet defined to go with sca..., later also some configure options ??
+//const defaultDownloadTimeout = 60 // (?) Seconds
+//const localImgPath = "/home/lcui/work/tmp"
+
+// ### downloadToAdapter  			    - end ####
+
+//AdapterDownloadManager structure holds information needed for downloading to and storing images within the adapter
+type AdapterDownloadManager struct {
+	mutexDownloadImageDsc sync.RWMutex
+	downloadImageDscSlice []*voltha.ImageDownload
+}
+
+//NewAdapterDownloadManager constructor returns a new instance of a AdapterDownloadManager
+//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
+func NewAdapterDownloadManager(ctx context.Context) *AdapterDownloadManager {
+	logger.Debug(ctx, "init-AdapterDownloadManager")
+	var localDnldMgr AdapterDownloadManager
+	localDnldMgr.downloadImageDscSlice = make([]*voltha.ImageDownload, 0)
+	return &localDnldMgr
+}
+
+//ImageExists returns true if the requested image already exists within the adapter
+func (dm *AdapterDownloadManager) ImageExists(ctx context.Context, apImageDsc *voltha.ImageDownload) bool {
+	logger.Debugw(ctx, "checking on existence of the image", log.Fields{"image-name": (*apImageDsc).Name})
+	dm.mutexDownloadImageDsc.RLock()
+	defer dm.mutexDownloadImageDsc.RUnlock()
+
+	for _, pDnldImgDsc := range dm.downloadImageDscSlice {
+		if (*pDnldImgDsc).Name == (*apImageDsc).Name {
+			//image found (by name)
+			return true
+		}
+	}
+	//image not found (by name)
+	return false
+}
+
+//ImageLocallyDownloaded returns true if the requested image already exists within the adapter
+func (dm *AdapterDownloadManager) ImageLocallyDownloaded(ctx context.Context, apImageDsc *voltha.ImageDownload) bool {
+	logger.Debugw(ctx, "checking if image is fully downloaded", log.Fields{"image-name": (*apImageDsc).Name})
+	dm.mutexDownloadImageDsc.RLock()
+	defer dm.mutexDownloadImageDsc.RUnlock()
+
+	for _, pDnldImgDsc := range dm.downloadImageDscSlice {
+		if (*pDnldImgDsc).Name == (*apImageDsc).Name {
+			//image found (by name)
+			if (*pDnldImgDsc).DownloadState == voltha.ImageDownload_DOWNLOAD_SUCCEEDED {
+				logger.Debugw(ctx, "image has been fully downloaded", log.Fields{"image-name": (*apImageDsc).Name})
+				return true
+			}
+			logger.Debugw(ctx, "image not yet fully downloaded", log.Fields{"image-name": (*apImageDsc).Name})
+			return false
+		}
+	}
+	//image not found (by name)
+	logger.Errorw(ctx, "image does not exist", log.Fields{"image-name": (*apImageDsc).Name})
+	return false
+}
+
+//StartDownload returns true if the download of the requested image could be started
+func (dm *AdapterDownloadManager) StartDownload(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
+	if apImageDsc.LocalDir != "" {
+		logger.Infow(ctx, "image download-to-adapter requested", log.Fields{
+			"image-path": apImageDsc.LocalDir, "image-name": apImageDsc.Name})
+		newImageDscPos := len(dm.downloadImageDscSlice)
+		dm.downloadImageDscSlice = append(dm.downloadImageDscSlice, apImageDsc)
+		dm.downloadImageDscSlice[newImageDscPos].DownloadState = voltha.ImageDownload_DOWNLOAD_STARTED
+		//try to download from http
+		urlName := apImageDsc.Url + "/" + apImageDsc.Name
+		err := dm.downloadFile(ctx, urlName, apImageDsc.LocalDir, apImageDsc.Name)
+		if err != nil {
+			return (err)
+		}
+		//return success to comfort the core processing during integration
+		return nil
+	}
+	// we can use the missing local path temporary also to test some failure behavior (system reation on failure)
+	// with updated control API's or at some adequate time we could also set some defined fixed localPath internally
+	logger.Errorw(ctx, "could not start download: no valid local directory to write to", log.Fields{"image-name": (*apImageDsc).Name})
+	return errors.New("could not start download: no valid local directory to write to")
+}
+
+//downloadFile downloads the specified file from the given http location
+func (dm *AdapterDownloadManager) downloadFile(ctx context.Context, aURLName string, aFilePath string, aFileName string) error {
+	// Get the data
+	logger.Infow(ctx, "downloading from http", log.Fields{"url": aURLName, "localPath": aFilePath})
+	// http command is already part of the aURLName argument
+	urlBase, err1 := url.Parse(aURLName)
+	if err1 != nil {
+		logger.Errorw(ctx, "could not set base url command", log.Fields{"url": aURLName, "error": err1})
+		return fmt.Errorf("could not set base url command: %s, error: %s", aURLName, err1)
+	}
+	urlParams := url.Values{}
+	urlBase.RawQuery = urlParams.Encode()
+
+	//pre-check on file existence
+	reqExist, errExist2 := http.NewRequest("HEAD", urlBase.String(), nil)
+	if errExist2 != nil {
+		logger.Errorw(ctx, "could not generate http head request", log.Fields{"url": urlBase.String(), "error": errExist2})
+		return fmt.Errorf("could not  generate http head request: %s, error: %s", aURLName, errExist2)
+	}
+	ctxExist, cancelExist := context.WithDeadline(ctx, time.Now().Add(3*time.Second)) //waiting for some fast answer
+	defer cancelExist()
+	_ = reqExist.WithContext(ctxExist)
+	respExist, errExist3 := http.DefaultClient.Do(reqExist)
+	if errExist3 != nil || (respExist != nil && respExist.StatusCode != http.StatusOK) {
+		if respExist != nil {
+			logger.Errorw(ctx, "could not http head from url", log.Fields{"url": urlBase.String(),
+				"error": errExist3, "status": respExist.StatusCode})
+			//if head is not supported by server we cannot use this test and just try to continue
+			if respExist.StatusCode != http.StatusMethodNotAllowed {
+				logger.Errorw(ctx, "http head from url: file does not exist here, aborting", log.Fields{"url": urlBase.String(),
+					"error": errExist3, "status": respExist.StatusCode})
+				return fmt.Errorf("http head from url: file does not exist here, aborting: %s, error: %s, status: %d",
+					aURLName, errExist2, respExist.StatusCode)
+			}
+		} else {
+			logger.Errorw(ctx, "could not http head from url", log.Fields{"url": urlBase.String(),
+				"error": errExist3})
+		}
+	}
+
+	if errExist3 == nil && respExist != nil {
+		defer func() {
+			deferredErr := respExist.Body.Close()
+			if deferredErr != nil {
+				logger.Errorw(ctx, "error at closing http head response body", log.Fields{"url": urlBase.String(), "error": deferredErr})
+			}
+		}()
+	}
+
+	//trying to download - do it in background as it may take some time ...
+	go dm.requestDownload(ctx, urlBase, aFilePath, aFileName)
+	return nil
+}
+
+func (dm *AdapterDownloadManager) requestDownload(ctx context.Context, urlBase *url.URL, aFilePath, aFileName string) {
+	req, err2 := http.NewRequest("GET", urlBase.String(), nil)
+	if err2 != nil {
+		logger.Errorw(ctx, "could not generate http request", log.Fields{"url": urlBase.String(), "error": err2})
+		return
+	}
+	ctx, cancel := context.WithDeadline(ctx, time.Now().Add(10*time.Second)) //long timeout for remote server and big file
+	defer cancel()
+	_ = req.WithContext(ctx)
+	resp, err3 := http.DefaultClient.Do(req)
+	if err3 != nil {
+		logger.Errorw(ctx, "could not http get from url", log.Fields{"url": urlBase.String(), "error": err3})
+		return
+	}
+	defer func() {
+		deferredErr := resp.Body.Close()
+		if deferredErr != nil {
+			logger.Errorw(ctx, "error at closing http get response body", log.Fields{"url": urlBase.String(), "error": deferredErr})
+		}
+	}()
+
+	if resp.StatusCode != http.StatusOK {
+		logger.Errorw(ctx, "could not http get from url", log.Fields{"url": urlBase.String(), "status": resp.StatusCode})
+		return
+	}
+
+	// Create the file
+	aLocalPathName := aFilePath + "/" + aFileName
+	file, err := os.Create(aLocalPathName)
+	if err != nil {
+		logger.Errorw(ctx, "could not create local file", log.Fields{"path_file": aLocalPathName, "error": err})
+		return
+	}
+	defer func() {
+		deferredErr := file.Close()
+		if deferredErr != nil {
+			logger.Errorw(ctx, "error at closing new file", log.Fields{"path_file": aLocalPathName, "error": deferredErr})
+		}
+	}()
+
+	// Write the body to file
+	_, err = io.Copy(file, resp.Body)
+	if err != nil {
+		logger.Errorw(ctx, "could not copy file content", log.Fields{"url": urlBase.String(), "file": aLocalPathName, "error": err})
+		return
+	}
+
+	fileStats, statsErr := file.Stat()
+	if statsErr != nil {
+		logger.Errorw(ctx, "created file can't be accessed", log.Fields{"file": aLocalPathName, "stat-error": statsErr})
+	}
+	if fileStats != nil {
+		logger.Infow(ctx, "written file size is", log.Fields{"file": aLocalPathName, "length": fileStats.Size()})
+	}
+
+	for _, pDnldImgDsc := range dm.downloadImageDscSlice {
+		if (*pDnldImgDsc).Name == aFileName {
+			//image found (by name)
+			(*pDnldImgDsc).DownloadState = voltha.ImageDownload_DOWNLOAD_SUCCEEDED
+			return //can leave directly
+		}
+	}
+}
+
+//getImageBufferLen returns the length of the specified file in bytes (file size)
+func (dm *AdapterDownloadManager) getImageBufferLen(ctx context.Context, aFileName string,
+	aLocalPath string) (int64, error) {
+	//maybe we can also use FileSize from dm.downloadImageDscSlice - future option?
+
+	file, err := os.Open(filepath.Clean(aLocalPath + "/" + aFileName))
+	if err != nil {
+		return 0, err
+	}
+	defer func() {
+		err := file.Close()
+		if err != nil {
+			logger.Errorw(ctx, "failed to close file", log.Fields{"error": err})
+		}
+	}()
+
+	stats, statsErr := file.Stat()
+	if statsErr != nil {
+		return 0, statsErr
+	}
+
+	return stats.Size(), nil
+}
+
+//getDownloadImageBuffer returns the content of the requested file as byte slice
+func (dm *AdapterDownloadManager) getDownloadImageBuffer(ctx context.Context, aFileName string,
+	aLocalPath string) ([]byte, error) {
+	file, err := os.Open(filepath.Clean(aLocalPath + "/" + aFileName))
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		err := file.Close()
+		if err != nil {
+			logger.Errorw(ctx, "failed to close file", log.Fields{"error": err})
+		}
+	}()
+
+	stats, statsErr := file.Stat()
+	if statsErr != nil {
+		return nil, statsErr
+	}
+
+	var size int64 = stats.Size()
+	bytes := make([]byte, size)
+
+	buffer := bufio.NewReader(file)
+	_, err = buffer.Read(bytes)
+
+	return bytes, err
+}
diff --git a/internal/pkg/swupg/common.go b/internal/pkg/swupg/common.go
new file mode 100755
index 0000000..b933bef
--- /dev/null
+++ b/internal/pkg/swupg/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 swupg provides the utilities for onu sw upgrade
+package swupg
+
+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": "swupg"})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/internal/pkg/swupg/file_download_manager.go b/internal/pkg/swupg/file_download_manager.go
new file mode 100755
index 0000000..900ba5a
--- /dev/null
+++ b/internal/pkg/swupg/file_download_manager.go
@@ -0,0 +1,452 @@
+/*
+ * 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 swupg provides the utilities for onu sw upgrade
+package swupg
+
+import (
+	"bufio"
+	"context"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"os"
+	"path/filepath"
+	"sync"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+const cDefaultLocalDir = "/tmp" //this is the default local dir to download to
+
+type fileState uint32
+
+//nolint:varcheck, deadcode
+const (
+	cFileStateUnknown fileState = iota
+	cFileStateDlStarted
+	cFileStateDlSucceeded
+	cFileStateDlFailed
+	cFileStateDlAborted
+	cFileStateDlInvalid
+)
+
+type downloadImageParams struct {
+	downloadImageName       string
+	downloadImageState      fileState
+	downloadImageLen        int64
+	downloadImageCrc        uint32
+	downloadActive          bool
+	downloadContextCancelFn context.CancelFunc
+}
+
+type requesterChannelMap map[chan<- bool]struct{} //using an empty structure map for easier (unique) element appending
+
+//FileDownloadManager structure holds information needed for downloading to and storing images within the adapter
+type FileDownloadManager struct {
+	mutexDownloadImageDsc sync.RWMutex
+	downloadImageDscSlice []downloadImageParams
+	dnldImgReadyWaiting   map[string]requesterChannelMap
+	dlToAdapterTimeout    time.Duration
+}
+
+//NewFileDownloadManager constructor returns a new instance of a FileDownloadManager
+//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
+func NewFileDownloadManager(ctx context.Context) *FileDownloadManager {
+	logger.Debug(ctx, "init-FileDownloadManager")
+	var localDnldMgr FileDownloadManager
+	localDnldMgr.downloadImageDscSlice = make([]downloadImageParams, 0)
+	localDnldMgr.dnldImgReadyWaiting = make(map[string]requesterChannelMap)
+	localDnldMgr.dlToAdapterTimeout = 10 * time.Second //default timeout, should be overwritten immediately after start
+	return &localDnldMgr
+}
+
+//SetDownloadTimeout configures the timeout used to supervice the download of the image to the adapter (assumed in seconds)
+func (dm *FileDownloadManager) SetDownloadTimeout(ctx context.Context, aDlTimeout time.Duration) {
+	dm.mutexDownloadImageDsc.Lock()
+	defer dm.mutexDownloadImageDsc.Unlock()
+	logger.Debugw(ctx, "setting download timeout", log.Fields{"timeout": aDlTimeout})
+	dm.dlToAdapterTimeout = aDlTimeout
+}
+
+//GetDownloadTimeout delivers the timeout used to supervice the download of the image to the adapter (assumed in seconds)
+func (dm *FileDownloadManager) GetDownloadTimeout(ctx context.Context) time.Duration {
+	dm.mutexDownloadImageDsc.RLock()
+	defer dm.mutexDownloadImageDsc.RUnlock()
+	return dm.dlToAdapterTimeout
+}
+
+//ImageExists returns true if the requested image already exists within the adapter
+func (dm *FileDownloadManager) ImageExists(ctx context.Context, aImageName string) bool {
+	logger.Debugw(ctx, "checking on existence of the image", log.Fields{"image-name": aImageName})
+	dm.mutexDownloadImageDsc.RLock()
+	defer dm.mutexDownloadImageDsc.RUnlock()
+
+	for _, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aImageName {
+			//image found (by name)
+			return true
+		}
+	}
+	//image not found (by name)
+	return false
+}
+
+//StartDownload returns true if the download of the requested image could be started for the given file name and URL
+func (dm *FileDownloadManager) StartDownload(ctx context.Context, aImageName string, aURLCommand string) error {
+	logger.Infow(ctx, "image download-to-adapter requested", log.Fields{
+		"image-name": aImageName, "url-command": aURLCommand})
+	loDownloadImageParams := downloadImageParams{
+		downloadImageName: aImageName, downloadImageState: cFileStateDlStarted,
+		downloadImageLen: 0, downloadImageCrc: 0}
+	//try to download from http
+	var err error
+	if err = dm.downloadFile(ctx, aURLCommand, cDefaultLocalDir, aImageName); err == nil {
+		dm.mutexDownloadImageDsc.Lock()
+		dm.downloadImageDscSlice = append(dm.downloadImageDscSlice, loDownloadImageParams)
+		dm.mutexDownloadImageDsc.Unlock()
+	}
+	//return the result of the start-request to comfort the core processing even though the complete download may go on in background
+	return err
+}
+
+//GetImageBufferLen returns the length of the specified file in bytes (file size) - as detected after download
+func (dm *FileDownloadManager) GetImageBufferLen(ctx context.Context, aFileName string) (int64, error) {
+	dm.mutexDownloadImageDsc.RLock()
+	defer dm.mutexDownloadImageDsc.RUnlock()
+	for _, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aFileName && dnldImgDsc.downloadImageState == cFileStateDlSucceeded {
+			//image found (by name) and fully downloaded
+			return dnldImgDsc.downloadImageLen, nil
+		}
+	}
+	return 0, fmt.Errorf("no downloaded image found: %s", aFileName)
+}
+
+//GetDownloadImageBuffer returns the content of the requested file as byte slice
+func (dm *FileDownloadManager) GetDownloadImageBuffer(ctx context.Context, aFileName string) ([]byte, error) {
+	file, err := os.Open(filepath.Clean(cDefaultLocalDir + "/" + aFileName))
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		err := file.Close()
+		if err != nil {
+			logger.Errorw(ctx, "failed to close file", log.Fields{"error": err})
+		}
+	}()
+
+	stats, statsErr := file.Stat()
+	if statsErr != nil {
+		return nil, statsErr
+	}
+
+	var size int64 = stats.Size()
+	bytes := make([]byte, size)
+
+	buffer := bufio.NewReader(file)
+	_, err = buffer.Read(bytes)
+
+	return bytes, err
+}
+
+//RequestDownloadReady receives a channel that has to be used to inform the requester in case the concerned file is downloaded
+func (dm *FileDownloadManager) RequestDownloadReady(ctx context.Context, aFileName string, aWaitChannel chan<- bool) {
+	//mutexDownloadImageDsc must already be locked here to avoid an update of the dnldImgReadyWaiting map
+	//  just after returning false on imageLocallyDownloaded() (not found) and immediate handling of the
+	//  download success (within updateFileState())
+	//  so updateFileState() can't interfere here just after imageLocallyDownloaded() before setting the requester map
+	dm.mutexDownloadImageDsc.Lock()
+	defer dm.mutexDownloadImageDsc.Unlock()
+	if dm.imageLocallyDownloaded(ctx, aFileName) {
+		//image found (by name) and fully downloaded
+		logger.Debugw(ctx, "file ready - immediate response", log.Fields{"image-name": aFileName})
+		aWaitChannel <- true
+		return
+	}
+	//when we are here the image was not yet found or not fully downloaded -
+	//  add the device specific channel to the list of waiting requesters
+	if loRequesterChannelMap, ok := dm.dnldImgReadyWaiting[aFileName]; ok {
+		//entry for the file name already exists
+		if _, exists := loRequesterChannelMap[aWaitChannel]; !exists {
+			// requester channel does not yet exist for the image
+			loRequesterChannelMap[aWaitChannel] = struct{}{}
+			dm.dnldImgReadyWaiting[aFileName] = loRequesterChannelMap
+			logger.Debugw(ctx, "file not ready - adding new requester", log.Fields{
+				"image-name": aFileName, "number-of-requesters": len(dm.dnldImgReadyWaiting[aFileName])})
+		}
+	} else {
+		//entry for the file name does not even exist
+		addRequesterChannelMap := make(map[chan<- bool]struct{})
+		addRequesterChannelMap[aWaitChannel] = struct{}{}
+		dm.dnldImgReadyWaiting[aFileName] = addRequesterChannelMap
+		logger.Debugw(ctx, "file not ready - setting first requester", log.Fields{
+			"image-name": aFileName})
+	}
+}
+
+//RemoveReadyRequest removes the specified channel from the requester(channel) map for the given file name
+func (dm *FileDownloadManager) RemoveReadyRequest(ctx context.Context, aFileName string, aWaitChannel chan bool) {
+	dm.mutexDownloadImageDsc.Lock()
+	defer dm.mutexDownloadImageDsc.Unlock()
+	for imageName, channelMap := range dm.dnldImgReadyWaiting {
+		if imageName == aFileName {
+			for channel := range channelMap {
+				if channel == aWaitChannel {
+					delete(dm.dnldImgReadyWaiting[imageName], channel)
+					logger.Debugw(ctx, "channel removed from the requester map", log.Fields{
+						"image-name": aFileName, "new number-of-requesters": len(dm.dnldImgReadyWaiting[aFileName])})
+					return //can leave directly
+				}
+			}
+			return //can leave directly
+		}
+	}
+}
+
+// FileDownloadManager private (unexported) methods -- start
+
+//imageLocallyDownloaded returns true if the requested image already exists within the adapter
+//  requires mutexDownloadImageDsc to be locked (at least RLocked)
+func (dm *FileDownloadManager) imageLocallyDownloaded(ctx context.Context, aImageName string) bool {
+	logger.Debugw(ctx, "checking if image is fully downloaded to adapter", log.Fields{"image-name": aImageName})
+	for _, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aImageName {
+			//image found (by name)
+			if dnldImgDsc.downloadImageState == cFileStateDlSucceeded {
+				logger.Debugw(ctx, "image has been fully downloaded", log.Fields{"image-name": aImageName})
+				return true
+			}
+			logger.Debugw(ctx, "image not yet fully downloaded", log.Fields{"image-name": aImageName})
+			return false
+		}
+	}
+	//image not found (by name)
+	logger.Errorw(ctx, "image does not exist", log.Fields{"image-name": aImageName})
+	return false
+}
+
+//updateDownloadCancel sets context cancel function to be used in case the download is to be aborted
+func (dm *FileDownloadManager) updateDownloadCancel(ctx context.Context,
+	aImageName string, aCancelFn context.CancelFunc) {
+	dm.mutexDownloadImageDsc.Lock()
+	defer dm.mutexDownloadImageDsc.Unlock()
+	for imgKey, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aImageName {
+			//image found (by name) - need to write changes on the original map
+			dm.downloadImageDscSlice[imgKey].downloadContextCancelFn = aCancelFn
+			dm.downloadImageDscSlice[imgKey].downloadActive = true
+			logger.Debugw(ctx, "downloadContextCancelFn set", log.Fields{
+				"image-name": aImageName})
+			return //can leave directly
+		}
+	}
+}
+
+//updateFileState sets the new active (downloaded) file state and informs possibly waiting requesters on this change
+func (dm *FileDownloadManager) updateFileState(ctx context.Context, aImageName string, aFileSize int64) {
+	dm.mutexDownloadImageDsc.Lock()
+	defer dm.mutexDownloadImageDsc.Unlock()
+	for imgKey, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aImageName {
+			//image found (by name) - need to write changes on the original map
+			dm.downloadImageDscSlice[imgKey].downloadActive = false
+			dm.downloadImageDscSlice[imgKey].downloadImageState = cFileStateDlSucceeded
+			dm.downloadImageDscSlice[imgKey].downloadImageLen = aFileSize
+			logger.Debugw(ctx, "imageState download succeeded", log.Fields{
+				"image-name": aImageName, "image-size": aFileSize})
+			//in case upgrade process(es) was/were waiting for the file, inform them
+			for imageName, channelMap := range dm.dnldImgReadyWaiting {
+				if imageName == aImageName {
+					for channel := range channelMap {
+						// use all found channels to inform possible requesters about the existence of the file
+						channel <- true
+						delete(dm.dnldImgReadyWaiting[imageName], channel) //requester served
+					}
+					return //can leave directly
+				}
+			}
+			return //can leave directly
+		}
+	}
+}
+
+//downloadFile downloads the specified file from the given http location
+func (dm *FileDownloadManager) downloadFile(ctx context.Context, aURLCommand string, aFilePath string, aFileName string) error {
+	// Get the data
+	logger.Infow(ctx, "downloading with URL", log.Fields{"url": aURLCommand, "localPath": aFilePath})
+	// verifying the complete URL by parsing it to its URL elements
+	urlBase, err1 := url.Parse(aURLCommand)
+	if err1 != nil {
+		logger.Errorw(ctx, "could not set base url command", log.Fields{"url": aURLCommand, "error": err1})
+		return fmt.Errorf("could not set base url command: %s, error: %s", aURLCommand, err1)
+	}
+	urlParams := url.Values{}
+	urlBase.RawQuery = urlParams.Encode()
+
+	//pre-check on file existence - assuming http location here
+	reqExist, errExist2 := http.NewRequest("HEAD", urlBase.String(), nil)
+	if errExist2 != nil {
+		logger.Errorw(ctx, "could not generate http head request", log.Fields{"url": urlBase.String(), "error": errExist2})
+		return fmt.Errorf("could not  generate http head request: %s, error: %s", aURLCommand, errExist2)
+	}
+	ctxExist, cancelExist := context.WithDeadline(ctx, time.Now().Add(3*time.Second)) //waiting for some fast answer
+	defer cancelExist()
+	_ = reqExist.WithContext(ctxExist)
+	respExist, errExist3 := http.DefaultClient.Do(reqExist)
+	if errExist3 != nil || respExist.StatusCode != http.StatusOK {
+		if respExist == nil {
+			logger.Errorw(ctx, "http head from url error - no status, aborting", log.Fields{"url": urlBase.String(),
+				"error": errExist3})
+			return fmt.Errorf("http head from url error - no status, aborting: %s, error: %s",
+				aURLCommand, errExist3)
+		}
+		logger.Infow(ctx, "could not http head from url", log.Fields{"url": urlBase.String(),
+			"error": errExist3, "status": respExist.StatusCode})
+		//if head is not supported by server we cannot use this test and just try to continue
+		if respExist.StatusCode != http.StatusMethodNotAllowed {
+			logger.Errorw(ctx, "http head from url: file does not exist here, aborting", log.Fields{"url": urlBase.String(),
+				"error": errExist3, "status": respExist.StatusCode})
+			return fmt.Errorf("http head from url: file does not exist here, aborting: %s, error: %s, status: %d",
+				aURLCommand, errExist3, respExist.StatusCode)
+		}
+	}
+	defer func() {
+		deferredErr := respExist.Body.Close()
+		if deferredErr != nil {
+			logger.Errorw(ctx, "error at closing http head response body", log.Fields{"url": urlBase.String(), "error": deferredErr})
+		}
+	}()
+
+	//trying to download - do it in background as it may take some time ...
+	go func() {
+		req, err2 := http.NewRequest("GET", urlBase.String(), nil)
+		if err2 != nil {
+			logger.Errorw(ctx, "could not generate http request", log.Fields{"url": urlBase.String(), "error": err2})
+			dm.removeImage(ctx, aFileName, false) //wo FileSystem access
+			return
+		}
+		ctx, cancel := context.WithDeadline(ctx, time.Now().Add(dm.dlToAdapterTimeout)) //timeout as given from SetDownloadTimeout()
+		dm.updateDownloadCancel(ctx, aFileName, cancel)
+		defer cancel()
+		_ = req.WithContext(ctx)
+		resp, err3 := http.DefaultClient.Do(req)
+		if err3 != nil || resp.StatusCode != http.StatusOK {
+			if resp == nil {
+				logger.Errorw(ctx, "http get error - no status, aborting", log.Fields{"url": urlBase.String(),
+					"error": err3})
+			} else {
+				logger.Errorw(ctx, "could not http get from url", log.Fields{"url": urlBase.String(),
+					"error": err3, "status": resp.StatusCode})
+			}
+			dm.removeImage(ctx, aFileName, false) //wo FileSystem access
+			return
+		}
+		defer func() {
+			deferredErr := resp.Body.Close()
+			if deferredErr != nil {
+				logger.Errorw(ctx, "error at closing http get response body", log.Fields{"url": urlBase.String(), "error": deferredErr})
+			}
+		}()
+
+		// Create the file
+		aLocalPathName := aFilePath + "/" + aFileName
+		file, err := os.Create(aLocalPathName)
+		if err != nil {
+			logger.Errorw(ctx, "could not create local file", log.Fields{"path_file": aLocalPathName, "error": err})
+			dm.removeImage(ctx, aFileName, false) //wo FileSystem access
+			return
+		}
+		defer func() {
+			deferredErr := file.Close()
+			if deferredErr != nil {
+				logger.Errorw(ctx, "error at closing new file", log.Fields{"path_file": aLocalPathName, "error": deferredErr})
+			}
+		}()
+
+		// Write the body to file
+		_, err = io.Copy(file, resp.Body)
+		if err != nil {
+			logger.Errorw(ctx, "could not copy file content", log.Fields{"url": urlBase.String(), "file": aLocalPathName, "error": err})
+			dm.removeImage(ctx, aFileName, true)
+			return
+		}
+
+		fileStats, statsErr := file.Stat()
+		if err != nil {
+			logger.Errorw(ctx, "created file can't be accessed", log.Fields{"file": aLocalPathName, "stat-error": statsErr})
+			return
+		}
+		fileSize := fileStats.Size()
+		logger.Infow(ctx, "written file size is", log.Fields{"file": aLocalPathName, "length": fileSize})
+
+		dm.updateFileState(ctx, aFileName, fileSize)
+		//TODO:!!! further extension could be provided here, e.g. already computing and possibly comparing the CRC, vendor check
+	}()
+	return nil
+}
+
+//removeImage deletes the given image according to the Image name from filesystem and downloadImageDscSlice
+func (dm *FileDownloadManager) removeImage(ctx context.Context, aImageName string, aDelFs bool) {
+	logger.Debugw(ctx, "remove the image from Adapter", log.Fields{"image-name": aImageName})
+	dm.mutexDownloadImageDsc.RLock()
+	defer dm.mutexDownloadImageDsc.RUnlock()
+
+	tmpSlice := dm.downloadImageDscSlice[:0]
+	for _, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aImageName {
+			//image found (by name)
+			logger.Debugw(ctx, "removing image", log.Fields{"image-name": aImageName})
+			if aDelFs {
+				//remove the image from filesystem
+				aLocalPathName := cDefaultLocalDir + "/" + aImageName
+				if err := os.Remove(aLocalPathName); err != nil {
+					// might be a temporary situation, when the file was not yet (completely) written
+					logger.Debugw(ctx, "image not removed from filesystem", log.Fields{
+						"image-name": aImageName, "error": err})
+				}
+			}
+			// and remove from the imageDsc slice by just not appending
+		} else {
+			tmpSlice = append(tmpSlice, dnldImgDsc)
+		}
+	}
+	dm.downloadImageDscSlice = tmpSlice
+	//image not found (by name)
+}
+
+//CancelDownload stops the download and clears all entires concerning this aimageName
+func (dm *FileDownloadManager) CancelDownload(ctx context.Context, aImageName string) {
+	// for the moment that would only support to wait for the download end and remove the image then
+	//   further reactions while still downloading can be considered with some effort, but does it make sense (synchronous load here!)
+	dm.mutexDownloadImageDsc.RLock()
+	for imgKey, dnldImgDsc := range dm.downloadImageDscSlice {
+		if dnldImgDsc.downloadImageName == aImageName {
+			//image found (by name) - need to to check on ongoing download
+			if dm.downloadImageDscSlice[imgKey].downloadActive {
+				//then cancel the download using the context cancel function
+				dm.downloadImageDscSlice[imgKey].downloadContextCancelFn()
+			}
+			//and remove possibly stored traces of this image
+			dm.mutexDownloadImageDsc.RUnlock()
+			go dm.removeImage(ctx, aImageName, true) //including the chance that nothing was yet written to FS, should not matter
+			return                                   //can leave directly
+		}
+	}
+	dm.mutexDownloadImageDsc.RUnlock()
+}
diff --git a/internal/pkg/swupg/omci_onu_upgrade.go b/internal/pkg/swupg/omci_onu_upgrade.go
new file mode 100755
index 0000000..dbcb141
--- /dev/null
+++ b/internal/pkg/swupg/omci_onu_upgrade.go
@@ -0,0 +1,1725 @@
+/*
+ * 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 swupg provides the utilities for onu sw upgrade
+package swupg
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"strconv"
+	"sync"
+	"time"
+
+	"github.com/boguslaw-wojcik/crc32a"
+	"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"
+	"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
+	"github.com/opencord/voltha-protos/v5/go/voltha"
+)
+
+const cMaxUint32 = ^uint32(0)
+
+const (
+	// internal predefined values - some off them should later be configurable (perhaps with theses as defaults)
+	cOmciDownloadSectionSize     = 31 //in bytes
+	cOmciDownloadWindowSizeLimit = 31 //in sections for window offset (windowSize(32)-1)
+	//cOmciDownloadWindowRetryMax  = 2    // max attempts for a specific window
+	cOmciSectionInterleaveMilliseconds = 0  //DownloadSection interleave time in milliseconds (0 for no delay)
+	cOmciEndSwDlDelaySeconds           = 1  //End Software Download delay after last section (may be also configurable?)
+	cWaitCountEndSwDl                  = 6  //maximum number of EndSwDl requests
+	cWaitDelayEndSwDlSeconds           = 10 //duration, how long is waited before next request on EndSwDl
+	//cOmciDownloadCompleteTimeout = 5400 //in s for the complete timeout (may be better scale to image size/ noOfWindows)
+)
+
+// events of config PON ANI port FSM
+const (
+	UpgradeEvStart              = "UpgradeEvStart"
+	UpgradeEvDisable            = "UpgradeEvDisable"
+	UpgradeEvAdapterDownload    = "UpgradeEvAdapterDownload"
+	UpgradeEvPrepareSwDownload  = "UpgradeEvPrepareSwDownload"
+	UpgradeEvRxStartSwDownload  = "UpgradeEvRxStartSwDownload"
+	UpgradeEvWaitWindowAck      = "UpgradeEvWaitWindowAck"
+	UpgradeEvContinueNextWindow = "UpgradeEvContinueNextWindow"
+	UpgradeEvEndSwDownload      = "UpgradeEvEndSwDownload"
+	UpgradeEvWaitEndDownload    = "UpgradeEvWaitEndDownload"
+	UpgradeEvContinueFinalize   = "UpgradeEvContinueFinalize"
+	UpgradeEvCheckImageName     = "UpgradeEvCheckImageName"
+	UpgradeEvWaitForActivate    = "UpgradeEvWaitForActivate"
+	UpgradeEvRequestActivate    = "UpgradeEvRequestActivate"
+	UpgradeEvActivationDone     = "UpgradeEvActivationDone"
+	UpgradeEvWaitForCommit      = "UpgradeEvWaitForCommit"
+	UpgradeEvCommitSw           = "UpgradeEvCommitSw"
+	UpgradeEvCheckCommitted     = "UpgradeEvCheckCommitted"
+
+	//UpgradeEvTimeoutSimple  = "UpgradeEvTimeoutSimple"
+	//UpgradeEvTimeoutMids    = "UpgradeEvTimeoutMids"
+	UpgradeEvReset           = "UpgradeEvReset"
+	UpgradeEvAbort           = "UpgradeEvAbort"
+	UpgradeEvRestart         = "UpgradeEvRestart"
+	UpgradeEvAbortSwDownload = "UpgradeEvAbortSwDownload"
+)
+
+// states of config PON ANI port FSM
+const (
+	UpgradeStDisabled           = "UpgradeStDisabled"
+	UpgradeStStarting           = "UpgradeStStarting"
+	UpgradeStWaitingAdapterDL   = "UpgradeStWaitingAdapterDL"
+	UpgradeStPreparingDL        = "UpgradeStPreparingDL"
+	UpgradeStDLSection          = "UpgradeStDLSection"
+	UpgradeStVerifyWindow       = "UpgradeStVerifyWindow"
+	UpgradeStFinalizeDL         = "UpgradeStFinalizeDL"
+	UpgradeStWaitEndDL          = "UpgradeStWaitEndDL"
+	UpgradeStCheckImageName     = "UpgradeStCheckImageName"
+	UpgradeStWaitForActivate    = "UpgradeStWaitForActivate"
+	UpgradeStRequestingActivate = "UpgradeStRequestingActivate"
+	UpgradeStActivated          = "UpgradeStActivated"
+	UpgradeStWaitForCommit      = "UpgradeStWaitForCommit"
+	UpgradeStCommitSw           = "UpgradeStCommitSw"
+	UpgradeStCheckCommitted     = "UpgradeStCheckCommitted"
+	UpgradeStResetting          = "UpgradeStResetting"
+	UpgradeStRestarting         = "UpgradeStRestarting"
+	UpgradeStAbortingDL         = "UpgradeStAbortingDL"
+)
+
+//COnuUpgradeFsmIdleState - required definition for IdleState detection for activities on OMCI
+const COnuUpgradeFsmIdleState = UpgradeStWaitForCommit
+
+//OnuUpgradeFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
+type OnuUpgradeFsm struct {
+	pDeviceHandler   cmn.IdeviceHandler
+	pDownloadManager *AdapterDownloadManager
+	pFileManager     *FileDownloadManager //used from R2.8 with new API version
+	deviceID         string
+	pDevEntry        cmn.IonuDeviceEntry
+	pOmciCC          *cmn.OmciCC
+	pOnuDB           *devdb.OnuDeviceDB
+	requestEvent     cmn.OnuDeviceEvent
+	//omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
+	PAdaptFsm                        *cmn.AdapterFsm
+	pImageDsc                        *voltha.ImageDownload
+	imageBuffer                      []byte
+	origImageLength                  uint32        //as also limited by OMCI
+	imageCRC                         uint32        //as per OMCI - ITU I.363.5 crc
+	imageLength                      uint32        //including last bytes padding
+	omciDownloadWindowSizeLimit      uint8         //windowSize-1 in sections
+	omciDownloadWindowSizeLast       uint8         //number of sections in last window
+	noOfSections                     uint32        //uint32 range for sections should be sufficient for very long images
+	nextDownloadSectionsAbsolute     uint32        //number of next section to download in overall image
+	nextDownloadSectionsWindow       uint8         //number of next section to download within current window
+	noOfWindows                      uint32        //uint32 range for windows should be sufficient for very long images
+	nextDownloadWindow               uint32        //number of next window to download
+	InactiveImageMeID                uint16        //ME-ID of the inactive image
+	downloadToOnuTimeout4MB          time.Duration //timeout for downloading the image to the ONU for a 4MB image slice
+	omciSectionInterleaveDelay       time.Duration //DownloadSectionInterleave delay in milliseconds
+	delayEndSwDl                     bool          //flag to provide a delay between last section and EndSwDl
+	pLastTxMeInstance                *me.ManagedEntity
+	waitCountEndSwDl                 uint8         //number, how often is waited for EndSwDl at maximum
+	waitDelayEndSwDl                 time.Duration //duration, how long is waited before next request on EndSwDl
+	chReceiveExpectedResponse        chan bool
+	useAPIVersion43                  bool         //flag for indication on which API version is used (and accordingly which specific methods)
+	mutexUpgradeParams               sync.RWMutex //mutex to protect members for parallel function requests and omci response processing
+	imageVersion                     string       //name of the image as used within OMCI (and on extrenal API interface)
+	imageIdentifier                  string       //name of the image as used in the adapter
+	mutexIsAwaitingAdapterDlResponse sync.RWMutex
+	chAdapterDlReady                 chan bool
+	isWaitingForAdapterDlResponse    bool
+	chOnuDlReady                     chan bool
+	activateImage                    bool
+	commitImage                      bool
+	mutexAbortRequest                sync.RWMutex
+	abortRequested                   voltha.ImageState_ImageFailureReason
+	conditionalCancelRequested       bool
+	volthaDownloadState              voltha.ImageState_ImageDownloadState
+	volthaDownloadReason             voltha.ImageState_ImageFailureReason
+	volthaImageState                 voltha.ImageState_ImageActivationState
+	isEndSwDlOpen                    bool
+	chReceiveAbortEndSwDlResponse    chan bool
+}
+
+//NewOnuUpgradeFsm is the 'constructor' for the state machine to config the PON ANI ports
+//  of ONU UNI ports via OMCI
+func NewOnuUpgradeFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler,
+	apDevEntry cmn.IonuDeviceEntry, apOnuDB *devdb.OnuDeviceDB,
+	aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message) *OnuUpgradeFsm {
+	instFsm := &OnuUpgradeFsm{
+		pDeviceHandler:              apDeviceHandler,
+		deviceID:                    apDeviceHandler.GetDeviceID(),
+		pDevEntry:                   apDevEntry,
+		pOmciCC:                     apDevEntry.GetDevOmciCC(),
+		pOnuDB:                      apOnuDB,
+		requestEvent:                aRequestEvent,
+		omciDownloadWindowSizeLimit: cOmciDownloadWindowSizeLimit,
+		omciSectionInterleaveDelay:  cOmciSectionInterleaveMilliseconds,
+		downloadToOnuTimeout4MB:     apDeviceHandler.GetDlToOnuTimeout4M(),
+		waitCountEndSwDl:            cWaitCountEndSwDl,
+		waitDelayEndSwDl:            cWaitDelayEndSwDlSeconds,
+		volthaDownloadState:         voltha.ImageState_DOWNLOAD_STARTED, //if FSM created we can assume that the download (to adapter) really started
+		volthaDownloadReason:        voltha.ImageState_NO_ERROR,
+		volthaImageState:            voltha.ImageState_IMAGE_UNKNOWN,
+		abortRequested:              voltha.ImageState_NO_ERROR,
+	}
+	instFsm.chReceiveExpectedResponse = make(chan bool)
+	instFsm.chAdapterDlReady = make(chan bool)
+	instFsm.chOnuDlReady = make(chan bool)
+	instFsm.chReceiveAbortEndSwDlResponse = make(chan bool)
+
+	instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
+	if instFsm.PAdaptFsm == nil {
+		logger.Errorw(ctx, "OnuUpgradeFsm's AdapterFsm could not be instantiated!!", log.Fields{
+			"device-id": instFsm.deviceID})
+		return nil
+	}
+	instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
+		UpgradeStDisabled,
+		fsm.Events{
+			{Name: UpgradeEvStart, Src: []string{UpgradeStDisabled}, Dst: UpgradeStStarting},
+			{Name: UpgradeEvAdapterDownload, Src: []string{UpgradeStStarting}, Dst: UpgradeStWaitingAdapterDL},
+			{Name: UpgradeEvPrepareSwDownload, Src: []string{UpgradeStStarting, UpgradeStWaitingAdapterDL}, Dst: UpgradeStPreparingDL},
+			{Name: UpgradeEvRxStartSwDownload, Src: []string{UpgradeStPreparingDL}, Dst: UpgradeStDLSection},
+			{Name: UpgradeEvWaitWindowAck, Src: []string{UpgradeStDLSection}, Dst: UpgradeStVerifyWindow},
+			{Name: UpgradeEvContinueNextWindow, Src: []string{UpgradeStVerifyWindow}, Dst: UpgradeStDLSection},
+			{Name: UpgradeEvEndSwDownload, Src: []string{UpgradeStVerifyWindow}, Dst: UpgradeStFinalizeDL},
+			{Name: UpgradeEvWaitEndDownload, Src: []string{UpgradeStFinalizeDL}, Dst: UpgradeStWaitEndDL},
+			{Name: UpgradeEvContinueFinalize, Src: []string{UpgradeStWaitEndDL}, Dst: UpgradeStFinalizeDL},
+			//UpgradeStCheckImageName only used with useAPIVersion43
+			{Name: UpgradeEvCheckImageName, Src: []string{UpgradeStWaitEndDL}, Dst: UpgradeStCheckImageName},
+			//UpgradeEvWaitForActivate state transitions depend on useAPIVersion43
+			{Name: UpgradeEvWaitForActivate, Src: []string{UpgradeStWaitEndDL, UpgradeStCheckImageName}, Dst: UpgradeStWaitForActivate},
+			//UpgradeEvRequestActivate state transitions depend on useAPIVersion43
+			{Name: UpgradeEvRequestActivate, Src: []string{UpgradeStStarting, UpgradeStWaitEndDL, UpgradeStCheckImageName,
+				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, UpgradeStRequestingActivate, UpgradeStWaitForCommit,
+				UpgradeStActivated}, Dst: UpgradeStCommitSw}, //allows also for direct commitment (without download) [TODO!!!]
+			{Name: UpgradeEvCheckCommitted, Src: []string{UpgradeStCommitSw}, Dst: UpgradeStCheckCommitted},
+
+			/*
+				{Name: UpgradeEvTimeoutSimple, Src: []string{
+					UpgradeStCreatingDot1PMapper, UpgradeStCreatingMBPCD, UpgradeStSettingTconts, UpgradeStSettingDot1PMapper}, Dst: UpgradeStStarting},
+				{Name: UpgradeEvTimeoutMids, Src: []string{
+					UpgradeStCreatingGemNCTPs, UpgradeStCreatingGemIWs, UpgradeStSettingPQs}, Dst: UpgradeStStarting},
+			*/
+			// exceptional treatments
+			//on UpgradeEvReset: UpgradeStRequestingActivate, 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, UpgradeStCheckImageName,
+				UpgradeStWaitForActivate,
+				UpgradeStCommitSw, UpgradeStCheckCommitted},
+				Dst: UpgradeStResetting},
+			{Name: UpgradeEvAbort, Src: []string{UpgradeStStarting, UpgradeStWaitingAdapterDL, UpgradeStPreparingDL, UpgradeStDLSection,
+				UpgradeStVerifyWindow, UpgradeStDLSection, UpgradeStFinalizeDL, UpgradeStWaitEndDL, UpgradeStCheckImageName,
+				UpgradeStWaitForActivate,
+				UpgradeStRequestingActivate, UpgradeStActivated, UpgradeStWaitForCommit,
+				UpgradeStCommitSw, UpgradeStCheckCommitted},
+				Dst: UpgradeStResetting},
+			{Name: UpgradeEvAbortSwDownload, Src: []string{UpgradeStResetting}, Dst: UpgradeStAbortingDL},
+			{Name: UpgradeEvRestart, Src: []string{UpgradeStResetting, UpgradeStAbortingDL}, Dst: UpgradeStRestarting},
+			{Name: UpgradeEvDisable, Src: []string{UpgradeStRestarting}, Dst: UpgradeStDisabled},
+		},
+		fsm.Callbacks{
+			"enter_state":                          func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
+			"enter_" + UpgradeStStarting:           func(e *fsm.Event) { instFsm.enterStarting(ctx, e) },
+			"enter_" + UpgradeStWaitingAdapterDL:   func(e *fsm.Event) { instFsm.enterWaitingAdapterDL(ctx, e) },
+			"enter_" + UpgradeStPreparingDL:        func(e *fsm.Event) { instFsm.enterPreparingDL(ctx, e) },
+			"enter_" + UpgradeStDLSection:          func(e *fsm.Event) { instFsm.enterDownloadSection(ctx, e) },
+			"enter_" + UpgradeStVerifyWindow:       func(e *fsm.Event) { instFsm.enterVerifyWindow(ctx, e) },
+			"enter_" + UpgradeStFinalizeDL:         func(e *fsm.Event) { instFsm.enterFinalizeDL(ctx, e) },
+			"enter_" + UpgradeStWaitEndDL:          func(e *fsm.Event) { instFsm.enterWaitEndDL(ctx, e) },
+			"enter_" + UpgradeStCheckImageName:     func(e *fsm.Event) { instFsm.enterCheckImageName(ctx, e) },
+			"enter_" + UpgradeStRequestingActivate: func(e *fsm.Event) { instFsm.enterActivateSw(ctx, e) },
+			"enter_" + UpgradeStCommitSw:           func(e *fsm.Event) { instFsm.enterCommitSw(ctx, e) },
+			"enter_" + UpgradeStCheckCommitted:     func(e *fsm.Event) { instFsm.enterCheckCommitted(ctx, e) },
+			"enter_" + UpgradeStResetting:          func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
+			"enter_" + UpgradeStAbortingDL:         func(e *fsm.Event) { instFsm.enterAbortingDL(ctx, e) },
+			"enter_" + UpgradeStRestarting:         func(e *fsm.Event) { instFsm.enterRestarting(ctx, e) },
+			"enter_" + UpgradeStDisabled:           func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
+		},
+	)
+	if instFsm.PAdaptFsm.PFsm == nil {
+		logger.Errorw(ctx, "OnuUpgradeFsm's Base FSM could not be instantiated!!", log.Fields{
+			"device-id": instFsm.deviceID})
+		return nil
+	}
+
+	logger.Debugw(ctx, "OnuUpgradeFsm created", log.Fields{"device-id": instFsm.deviceID})
+	return instFsm
+}
+
+//SetDownloadParams configures the needed parameters for a specific download to the ONU
+//  called from 'old' API Activate_image_update()
+func (oFsm *OnuUpgradeFsm) SetDownloadParams(ctx context.Context, aInactiveImageID uint16,
+	apImageDsc *voltha.ImageDownload, apDownloadManager *AdapterDownloadManager) error {
+	pBaseFsm := oFsm.PAdaptFsm.PFsm
+	if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
+		oFsm.mutexUpgradeParams.Lock()
+		logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
+			"device-id": oFsm.deviceID, "image-description": apImageDsc})
+		oFsm.InactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
+		oFsm.pImageDsc = apImageDsc
+		oFsm.pDownloadManager = apDownloadManager
+		oFsm.activateImage = true
+		oFsm.commitImage = true
+		oFsm.mutexUpgradeParams.Unlock()
+
+		go func(aPBaseFsm *fsm.FSM) {
+			// let the upgrade FSM proceed to PreparingDL
+			_ = aPBaseFsm.Event(UpgradeEvPrepareSwDownload)
+		}(pBaseFsm)
+		return nil
+	}
+	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
+		"device-id": oFsm.deviceID})
+	return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
+}
+
+//SetDownloadParamsAfterDownload configures the needed parameters for a specific download to the ONU according to
+//  updated API interface with R2.8: start download to ONU if the image is downloaded to the adapter
+//  called from 'new' API Download_onu_image
+func (oFsm *OnuUpgradeFsm) SetDownloadParamsAfterDownload(ctx context.Context, aInactiveImageID uint16,
+	apImageRequest *voltha.DeviceImageDownloadRequest, apDownloadManager *FileDownloadManager,
+	aImageIdentifier string) error {
+	oFsm.mutexUpgradeParams.Lock()
+	var pBaseFsm *fsm.FSM = nil
+	if oFsm.PAdaptFsm != nil {
+		pBaseFsm = oFsm.PAdaptFsm.PFsm
+	}
+	if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
+		logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting", log.Fields{
+			"device-id": oFsm.deviceID, "image-description": apImageRequest})
+		oFsm.useAPIVersion43 = true
+		oFsm.InactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
+		oFsm.pFileManager = apDownloadManager
+		oFsm.imageIdentifier = aImageIdentifier
+		oFsm.imageVersion = apImageRequest.Image.Version
+		oFsm.activateImage = apImageRequest.ActivateOnSuccess
+		oFsm.commitImage = apImageRequest.CommitOnSuccess
+		//TODO: currently straightforward options activate and commit are expected to be set and (unconditionally) done
+		//  for separate handling of these options the FSM must accordingly branch from the concerned states - later
+		oFsm.mutexUpgradeParams.Unlock()
+		_ = pBaseFsm.Event(UpgradeEvAdapterDownload) //no need to call the FSM event in background here
+		return nil
+	}
+	oFsm.mutexUpgradeParams.Unlock()
+	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
+		"device-id": oFsm.deviceID})
+	return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
+}
+
+//SetActivationParamsRunning sets the activate and commit flags for a running download to the ONU according to adapters rpc call
+//  called from 'new' API Activate_onu_image
+func (oFsm *OnuUpgradeFsm) SetActivationParamsRunning(ctx context.Context,
+	aImageIdentifier string, aCommit bool) error {
+	oFsm.mutexUpgradeParams.Lock()
+	//set activate/commit independent from state, if FSM is already beyond concerned states, then it does not matter anyway
+	//  (as long as the Imageidentifier is correct)
+	logger.Debugw(ctx, "OnuUpgradeFsm activate/commit parameter setting", log.Fields{
+		"device-id": oFsm.deviceID, "image-id": aImageIdentifier, "commit": aCommit})
+	if aImageIdentifier != oFsm.imageIdentifier {
+		logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
+			"device-id": oFsm.deviceID, "request-image": aImageIdentifier, "fsm-image": oFsm.imageIdentifier})
+		oFsm.mutexUpgradeParams.Unlock()
+		return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
+			oFsm.deviceID))
+	}
+	oFsm.activateImage = true
+	oFsm.commitImage = aCommit
+	var pBaseFsm *fsm.FSM = nil
+	if oFsm.PAdaptFsm != nil {
+		pBaseFsm = oFsm.PAdaptFsm.PFsm
+	}
+	if pBaseFsm != nil {
+		if pBaseFsm.Is(UpgradeStWaitForActivate) {
+			oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_STARTED //better choice would be 'UpgradeState=Started'
+			oFsm.mutexUpgradeParams.Unlock()
+			logger.Debugw(ctx, "OnuUpgradeFsm finish waiting for activate", log.Fields{"device-id": oFsm.deviceID})
+			_ = pBaseFsm.Event(UpgradeEvRequestActivate) //no need to call the FSM event in background here
+		} else {
+			oFsm.mutexUpgradeParams.Unlock()
+			logger.Debugw(ctx, "OnuUpgradeFsm not (yet?) waiting for activate", log.Fields{
+				"device-id": oFsm.deviceID, "current FsmState": pBaseFsm.Current()})
+		}
+		return nil
+	}
+	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
+		"device-id": oFsm.deviceID})
+	return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
+}
+
+//SetActivationParamsStart starts upgrade processing with immediate activation
+//  called from 'new' API Activate_onu_image
+func (oFsm *OnuUpgradeFsm) SetActivationParamsStart(ctx context.Context, aImageVersion string, aInactiveImageID uint16, aCommit bool) error {
+	oFsm.mutexUpgradeParams.Lock()
+	var pBaseFsm *fsm.FSM = nil
+	if oFsm.PAdaptFsm != nil {
+		pBaseFsm = oFsm.PAdaptFsm.PFsm
+	}
+	if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
+		logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with activation", log.Fields{
+			"device-id": oFsm.deviceID, "image-version": aImageVersion})
+		oFsm.useAPIVersion43 = true
+		oFsm.InactiveImageMeID = aInactiveImageID //upgrade state machines run on configured inactive ImageId
+		oFsm.imageVersion = aImageVersion
+		oFsm.activateImage = true
+		oFsm.commitImage = aCommit
+		// indicate start of the upgrade activity
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_STARTED //better choice would be 'UpgradeState=Started'
+		oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE      //as simply applied for inactive image
+		oFsm.mutexUpgradeParams.Unlock()
+		//directly request the FSM to activate the image
+		_ = pBaseFsm.Event(UpgradeEvRequestActivate) //no need to call the FSM event in background here
+		return nil
+	}
+	oFsm.mutexUpgradeParams.Unlock()
+	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
+		"device-id": oFsm.deviceID})
+	return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
+}
+
+//SetCommitmentParamsRunning sets the commit flag for a running download to the ONU according to adapters rpc call
+//  called from 'new' API Commit_onu_image
+func (oFsm *OnuUpgradeFsm) SetCommitmentParamsRunning(ctx context.Context,
+	aImageIdentifier string, aImageVersion string) error {
+	oFsm.mutexUpgradeParams.Lock()
+	//set commit independent from state, if FSM is already beyond commit state (just ready), then it does not matter anyway
+	//  (as long as the Imageidentifier is correct)
+	logger.Debugw(ctx, "OnuUpgradeFsm commit parameter setting", log.Fields{
+		"device-id": oFsm.deviceID, "image-id": aImageIdentifier})
+	if (aImageIdentifier != oFsm.imageIdentifier) && (aImageVersion != oFsm.imageVersion) {
+		logger.Errorw(ctx, "OnuUpgradeFsm abort: mismatching upgrade image", log.Fields{
+			"device-id": oFsm.deviceID, "request-identifier": aImageIdentifier, "fsm-identifier": oFsm.imageIdentifier,
+			"request-version": aImageVersion, "fsm-version": oFsm.imageVersion})
+		oFsm.mutexUpgradeParams.Unlock()
+		return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm params ignored: requested image-name not used in current upgrade for device-id: %s",
+			oFsm.deviceID))
+	}
+	oFsm.commitImage = true
+	oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_STARTED //better choice would be 'UpgradeState=Started'
+	oFsm.mutexUpgradeParams.Unlock()
+	var pBaseFsm *fsm.FSM = nil
+	if oFsm.PAdaptFsm != nil {
+		pBaseFsm = oFsm.PAdaptFsm.PFsm
+	}
+	if pBaseFsm != nil {
+		//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
+	}
+	//should never occur
+	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer", log.Fields{
+		"device-id": oFsm.deviceID})
+	return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer for device-id: %s", oFsm.deviceID))
+}
+
+//SetCommitmentParamsStart starts upgrade processing with immediate commitment
+//  called from 'new' API Commit_onu_image
+func (oFsm *OnuUpgradeFsm) SetCommitmentParamsStart(ctx context.Context, aImageVersion string, aActiveImageID uint16) error {
+	oFsm.mutexUpgradeParams.Lock()
+	var pBaseFsm *fsm.FSM = nil
+	if oFsm.PAdaptFsm != nil {
+		pBaseFsm = oFsm.PAdaptFsm.PFsm
+	}
+	if pBaseFsm != nil && pBaseFsm.Is(UpgradeStStarting) {
+		logger.Debugw(ctx, "OnuUpgradeFsm Parameter setting to start with commitment", log.Fields{
+			"device-id": oFsm.deviceID, "image-version": aImageVersion})
+		oFsm.useAPIVersion43 = true
+		oFsm.InactiveImageMeID = aActiveImageID //upgrade state machines inactive ImageId is the new active ImageId
+		oFsm.imageVersion = aImageVersion
+		oFsm.commitImage = true
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_STARTED //better choice would be 'UpgradeState=Started'
+		oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVE        //as simply applied for active image
+		oFsm.mutexUpgradeParams.Unlock()
+		//directly request the FSM to commit the image
+		_ = pBaseFsm.Event(UpgradeEvCommitSw) //no need to call the FSM event in background here
+		return nil
+	}
+	oFsm.mutexUpgradeParams.Unlock()
+	logger.Errorw(ctx, "OnuUpgradeFsm abort: invalid FSM base pointer or state", log.Fields{
+		"device-id": oFsm.deviceID})
+	return fmt.Errorf(fmt.Sprintf("OnuUpgradeFsm abort: invalid FSM base pointer or state for device-id: %s", oFsm.deviceID))
+}
+
+//GetCommitFlag delivers the commit flag that was configured here
+func (oFsm *OnuUpgradeFsm) GetCommitFlag(ctx context.Context) bool {
+	oFsm.mutexUpgradeParams.RLock()
+	defer oFsm.mutexUpgradeParams.RUnlock()
+	return oFsm.commitImage
+}
+
+//GetImageStates delivers the download/image states as per device proto buf definition
+func (oFsm *OnuUpgradeFsm) GetImageStates(ctx context.Context,
+	aImageIdentifier string, aVersion string) *voltha.ImageState {
+	pImageState := &voltha.ImageState{}
+	pImageState.Version = aVersion //version as requested
+	// check if the request refers to some active image/version of the processing
+	oFsm.mutexUpgradeParams.RLock()
+	if (aImageIdentifier == oFsm.imageIdentifier) || (aVersion == oFsm.imageVersion) {
+		pImageState.DownloadState = oFsm.volthaDownloadState
+		pImageState.Reason = oFsm.volthaDownloadReason
+		pImageState.ImageState = oFsm.volthaImageState
+	} else {
+		pImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
+		pImageState.Reason = voltha.ImageState_NO_ERROR
+		pImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
+	}
+	oFsm.mutexUpgradeParams.RUnlock()
+	return pImageState
+}
+
+//GetSpecificImageState delivers ImageState of the download/image states as per device proto buf definition
+func (oFsm *OnuUpgradeFsm) GetSpecificImageState(ctx context.Context) voltha.ImageState_ImageActivationState {
+	oFsm.mutexUpgradeParams.RLock()
+	imageState := oFsm.volthaImageState
+	oFsm.mutexUpgradeParams.RUnlock()
+	return imageState
+}
+
+//SetImageStateActive sets the FSM internal volthaImageState to ImageState_IMAGE_ACTIVE
+func (oFsm *OnuUpgradeFsm) SetImageStateActive(ctx context.Context) {
+	oFsm.mutexUpgradeParams.Lock()
+	defer oFsm.mutexUpgradeParams.Unlock()
+	oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVE
+	if !oFsm.commitImage {
+		//if commit is not additionally set, regard the upgrade activity as successful
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED //better choice would be 'UpgradeState=Succeeded'
+	}
+}
+
+//GetImageVersion delivers image-version of the running upgrade
+func (oFsm *OnuUpgradeFsm) GetImageVersion(ctx context.Context) string {
+	oFsm.mutexUpgradeParams.RLock()
+	imageVersion := oFsm.imageVersion
+	oFsm.mutexUpgradeParams.RUnlock()
+	return imageVersion
+}
+
+//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
+func (oFsm *OnuUpgradeFsm) CancelProcessing(ctx context.Context, abCompleteAbort bool,
+	aReason voltha.ImageState_ImageFailureReason) {
+	oFsm.mutexAbortRequest.Lock()
+	oFsm.abortRequested = aReason //possibly abort the sectionDownload loop
+	oFsm.mutexAbortRequest.Unlock()
+	//mutex protection is required for possible concurrent access to FSM members
+	//attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
+	// accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
+	oFsm.mutexIsAwaitingAdapterDlResponse.RLock()
+	if oFsm.isWaitingForAdapterDlResponse {
+		oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
+		//use channel to indicate that the download response waiting shall be aborted for this device (channel)
+		oFsm.chAdapterDlReady <- false
+	} else {
+		oFsm.mutexIsAwaitingAdapterDlResponse.RUnlock()
+	}
+	//chOnuDlReady is cleared as part of the FSM reset processing (from enterResetting())
+
+	// in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
+	// specific here: See definition of state changes: some states are excluded from reset for possible later commit
+	PAdaptFsm := oFsm.PAdaptFsm
+	if PAdaptFsm != nil {
+		// calling FSM events in background to avoid blocking of the caller
+		go func(aPAFsm *cmn.AdapterFsm) {
+			if aPAFsm.PFsm != nil {
+				if aPAFsm.PFsm.Is(UpgradeStWaitEndDL) {
+					oFsm.chReceiveExpectedResponse <- false //which aborts the FSM in WaitEndDL state
+				}
+				// in case of state-conditional request the
+
+				var err error
+				if abCompleteAbort {
+					oFsm.mutexUpgradeParams.Lock()
+					//any previous lingering conditional cancelRequest is superseded by this abortion
+					oFsm.conditionalCancelRequested = false
+					if aReason == voltha.ImageState_CANCELLED_ON_REQUEST {
+						oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
+					} else {
+						oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+					}
+					oFsm.volthaDownloadReason = aReason
+					oFsm.mutexUpgradeParams.Unlock()
+					err = aPAFsm.PFsm.Event(UpgradeEvAbort) //as unconditional default FSM cancellation
+				} else {
+					//at conditional request the image states are set when reaching the reset state
+					oFsm.conditionalCancelRequested = true
+					err = aPAFsm.PFsm.Event(UpgradeEvReset) //as state-conditional default FSM cleanup
+				}
+				if err != nil {
+					//error return is expected in case of conditional request and no state transition
+					logger.Debugw(ctx, "onu upgrade fsm could not cancel with abort/reset event", log.Fields{
+						"device-id": oFsm.deviceID, "error": err})
+				}
+			} //else the FSM seems already to be in some released state
+		}(PAdaptFsm)
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) enterStarting(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm start", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.deviceID})
+
+	// start go routine for processing of LockState messages
+	go oFsm.processOmciUpgradeMessages(ctx)
+}
+
+//enterWaitingAdapterDL state can only be reached with useAPIVersion43
+func (oFsm *OnuUpgradeFsm) enterWaitingAdapterDL(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm waiting for adapter download", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.deviceID})
+	syncChannel := make(chan struct{})
+	go oFsm.waitOnDownloadToAdapterReady(ctx, syncChannel, oFsm.chAdapterDlReady)
+	//block until the wait routine is really blocked on chAdapterDlReady
+	<-syncChannel
+	go oFsm.pFileManager.RequestDownloadReady(ctx, oFsm.imageIdentifier, oFsm.chAdapterDlReady)
+}
+
+func (oFsm *OnuUpgradeFsm) enterPreparingDL(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm prepare Download to Onu", log.Fields{"in state": e.FSM.Current(),
+		"device-id": oFsm.deviceID})
+
+	var fileLen int64
+	var err error
+	oFsm.mutexUpgradeParams.Lock()
+	if oFsm.useAPIVersion43 {
+		//with the new API structure download to adapter is implicit and we have to wait until the image is available
+		fileLen, err = oFsm.pFileManager.GetImageBufferLen(ctx, oFsm.imageIdentifier)
+	} else {
+		fileLen, err = oFsm.pDownloadManager.getImageBufferLen(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
+	}
+	if err != nil || fileLen > int64(cMaxUint32) {
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+		oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'LOCAL_FILE_ERROR' would be better (proto)
+		oFsm.volthaImageState = voltha.ImageState_IMAGE_UNKNOWN
+		oFsm.mutexUpgradeParams.Unlock()
+		logger.Errorw(ctx, "OnuUpgradeFsm abort: problems getting image buffer length", log.Fields{
+			"device-id": oFsm.deviceID, "error": err, "length": fileLen})
+		pBaseFsm := oFsm.PAdaptFsm
+		// Can't call FSM Event directly, decoupling it
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+		}(pBaseFsm)
+		return
+	}
+
+	//copy file content to buffer
+	oFsm.imageBuffer = make([]byte, fileLen)
+	if oFsm.useAPIVersion43 {
+		oFsm.imageBuffer, err = oFsm.pFileManager.GetDownloadImageBuffer(ctx, oFsm.imageIdentifier)
+	} else {
+		oFsm.imageBuffer, err = oFsm.pDownloadManager.getDownloadImageBuffer(ctx, oFsm.pImageDsc.Name, oFsm.pImageDsc.LocalDir)
+	}
+	if err != nil {
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+		oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'LOCAL_FILE_ERROR' would be better (proto)
+		oFsm.volthaImageState = voltha.ImageState_IMAGE_UNKNOWN
+		oFsm.mutexUpgradeParams.Unlock()
+		logger.Errorw(ctx, "OnuUpgradeFsm abort: can't get image buffer", log.Fields{
+			"device-id": oFsm.deviceID, "error": err})
+		pBaseFsm := oFsm.PAdaptFsm
+		// Can't call FSM Event directly, decoupling it
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+		}(pBaseFsm)
+		return
+	}
+
+	oFsm.noOfSections = uint32(fileLen / cOmciDownloadSectionSize)
+	if fileLen%cOmciDownloadSectionSize > 0 {
+		bufferPadding := make([]byte, cOmciDownloadSectionSize-uint32((fileLen)%cOmciDownloadSectionSize))
+		//expand the imageBuffer to exactly fit multiples of cOmciDownloadSectionSize with padding
+		oFsm.imageBuffer = append(oFsm.imageBuffer[:(fileLen)], bufferPadding...)
+		oFsm.noOfSections++
+	}
+	oFsm.origImageLength = uint32(fileLen)
+	oFsm.imageLength = uint32(len(oFsm.imageBuffer))
+	logger.Infow(ctx, "OnuUpgradeFsm starts with StartSwDl values", log.Fields{
+		"MeId": oFsm.InactiveImageMeID, "windowSizeLimit": oFsm.omciDownloadWindowSizeLimit,
+		"ImageSize": oFsm.imageLength, "original file size": fileLen})
+	//"NumberOfCircuitPacks": oFsm.numberCircuitPacks, "CircuitPacks MeId": 0}) //parallel circuit packs download not supported
+
+	oFsm.mutexUpgradeParams.Unlock()
+
+	// flush commMetricsChan
+	select {
+	case <-oFsm.chOnuDlReady:
+		logger.Debug(ctx, "flushed OnuDlReady channel")
+	default:
+	}
+	go oFsm.waitOnDownloadToOnuReady(ctx, oFsm.chOnuDlReady) // start supervision of the complete download-to-ONU procedure
+
+	err = oFsm.pOmciCC.SendStartSoftwareDownload(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
+		oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, oFsm.omciDownloadWindowSizeLimit, oFsm.origImageLength)
+	if err != nil {
+		logger.Errorw(ctx, "StartSwDl abort: can't send section", log.Fields{
+			"device-id": oFsm.deviceID, "error": err})
+		oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+		return
+	}
+	oFsm.isEndSwDlOpen = true
+}
+
+func (oFsm *OnuUpgradeFsm) enterDownloadSection(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm start downloading sections", log.Fields{
+		"device-id": oFsm.deviceID, "absolute window": oFsm.nextDownloadWindow})
+
+	var windowAckRequest uint8 = 0
+	var bufferStartOffset uint32
+	var bufferEndOffset uint32
+	var downloadSection []byte
+	FramePrint := false //default no printing of downloadSection frames
+	oFsm.mutexUpgradeParams.Lock()
+	if oFsm.nextDownloadSectionsAbsolute == 0 {
+		//debug print of first section frame
+		FramePrint = true
+		oFsm.volthaImageState = voltha.ImageState_IMAGE_DOWNLOADING
+	}
+
+	for {
+		oFsm.mutexAbortRequest.RLock()
+		// this way out of the section download loop on abort request
+		if oFsm.abortRequested != voltha.ImageState_NO_ERROR {
+			if oFsm.abortRequested == voltha.ImageState_CANCELLED_ON_REQUEST {
+				oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
+			} else {
+				oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+			}
+			oFsm.volthaDownloadReason = oFsm.abortRequested
+			oFsm.mutexAbortRequest.RUnlock()
+			oFsm.mutexUpgradeParams.Unlock()
+			pBaseFsm := oFsm.PAdaptFsm
+			// Can't call FSM Event directly, decoupling it
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+			}(pBaseFsm)
+			return
+		}
+		oFsm.mutexAbortRequest.RUnlock()
+
+		bufferStartOffset = oFsm.nextDownloadSectionsAbsolute * cOmciDownloadSectionSize
+		bufferEndOffset = bufferStartOffset + cOmciDownloadSectionSize - 1 //for representing cOmciDownloadSectionSizeLimit values
+		logger.Debugw(ctx, "DlSection values are", log.Fields{
+			"DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute,
+			"DlSectionWindow":     oFsm.nextDownloadSectionsWindow,
+			"startOffset":         bufferStartOffset, "endOffset": bufferEndOffset})
+		if bufferStartOffset+1 > oFsm.imageLength || bufferEndOffset+1 > oFsm.imageLength { //should never occur in this state
+			logger.Errorw(ctx, "OnuUpgradeFsm buffer error: exceeded length", log.Fields{
+				"device-id": oFsm.deviceID, "bufferStartOffset": bufferStartOffset,
+				"bufferEndOffset": bufferEndOffset, "imageLength": oFsm.imageLength})
+			oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+			oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'LOCAL_FILE_ERROR' would be better (proto)
+			oFsm.mutexUpgradeParams.Unlock()
+			//logical error -- reset the FSM
+			pBaseFsm := oFsm.PAdaptFsm
+			// Can't call FSM Event directly, decoupling it
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+			}(pBaseFsm)
+			return
+		}
+		downloadSection = oFsm.imageBuffer[bufferStartOffset : bufferEndOffset+1]
+		if oFsm.nextDownloadSectionsWindow == oFsm.omciDownloadWindowSizeLimit {
+			windowAckRequest = 1
+			logger.Debugw(ctx, "DlSection expect Response for complete window", log.Fields{
+				"device-id": oFsm.deviceID, "in window": oFsm.nextDownloadWindow})
+		}
+		if oFsm.nextDownloadSectionsAbsolute+1 >= oFsm.noOfSections {
+			windowAckRequest = 1
+			FramePrint = true //debug print of last frame
+			oFsm.omciDownloadWindowSizeLast = oFsm.nextDownloadSectionsWindow
+			logger.Infow(ctx, "DlSection expect Response for last window (section)", log.Fields{
+				"device-id": oFsm.deviceID, "DlSectionNoAbsolute": oFsm.nextDownloadSectionsAbsolute})
+		}
+		oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
+		err := oFsm.pOmciCC.SendDownloadSection(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
+			oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, windowAckRequest, oFsm.nextDownloadSectionsWindow, downloadSection, FramePrint)
+		if err != nil {
+			logger.Errorw(ctx, "DlSection abort: can't send section", log.Fields{
+				"device-id": oFsm.deviceID, "section absolute": oFsm.nextDownloadSectionsAbsolute, "error": err})
+			oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+			return
+		}
+		oFsm.mutexUpgradeParams.Lock()
+		oFsm.nextDownloadSectionsAbsolute++ //always increase the absolute section counter after having sent one
+		if windowAckRequest == 1 {
+			pBaseFsm := oFsm.PAdaptFsm
+			// Can't call FSM Event directly, decoupling it
+			oFsm.mutexUpgradeParams.Unlock()
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvWaitWindowAck) //state transition to UpgradeStVerifyWindow
+			}(pBaseFsm)
+			return
+		}
+		FramePrint = false                //for the next Section frame (if wanted, can be enabled in logic before sendXXX())
+		oFsm.nextDownloadSectionsWindow++ //increase the window related section counter only if not in the last section
+		if oFsm.omciSectionInterleaveDelay > 0 {
+			//ensure a defined intersection-time-gap to leave space for further processing, other ONU's ...
+			oFsm.mutexUpgradeParams.Unlock() //unlock here to give other functions some chance to process during/after the send request
+			time.Sleep(oFsm.omciSectionInterleaveDelay * time.Millisecond)
+			oFsm.mutexUpgradeParams.Lock()
+		}
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) enterVerifyWindow(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm verify DL window ack", log.Fields{
+		"for window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
+}
+
+func (oFsm *OnuUpgradeFsm) enterFinalizeDL(ctx context.Context, e *fsm.Event) {
+	logger.Infow(ctx, "OnuUpgradeFsm finalize DL", log.Fields{
+		"device-id": oFsm.deviceID, "crc": strconv.FormatInt(int64(oFsm.imageCRC), 16), "delay": oFsm.delayEndSwDl})
+
+	oFsm.mutexUpgradeParams.RLock()
+	if oFsm.delayEndSwDl {
+		oFsm.mutexUpgradeParams.RUnlock()
+		//give the ONU some time for image evaluation (hoping it does not base that on first EndSwDl itself)
+		// should not be set in case this state is used for real download abort (not yet implemented)
+		time.Sleep(cOmciEndSwDlDelaySeconds * time.Second)
+	} else {
+		oFsm.mutexUpgradeParams.RUnlock()
+	}
+
+	pBaseFsm := oFsm.PAdaptFsm
+	if pBaseFsm == nil {
+		logger.Errorw(ctx, "EndSwDl abort: BaseFsm invalid", log.Fields{"device-id": oFsm.deviceID})
+		oFsm.mutexUpgradeParams.Lock()
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+		oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR
+		oFsm.mutexUpgradeParams.Unlock()
+		// Can't call FSM Event directly, decoupling it
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+		}(pBaseFsm)
+		return
+	}
+	err := oFsm.pOmciCC.SendEndSoftwareDownload(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
+		oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, oFsm.origImageLength, oFsm.imageCRC)
+
+	oFsm.isEndSwDlOpen = false // also to be reset in case of OMCI error, as further send attempts would not make sense
+	if err != nil {
+		logger.Errorw(ctx, "EndSwDl abort: can't send section", log.Fields{
+			"device-id": oFsm.deviceID, "error": err})
+		oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+		return
+	}
+	// go waiting for the EndSwDLResponse and check, if the ONU is ready for activation
+	// Can't call FSM Event directly, decoupling it
+	go func(a_pAFsm *cmn.AdapterFsm) {
+		_ = a_pAFsm.PFsm.Event(UpgradeEvWaitEndDownload)
+	}(pBaseFsm)
+}
+
+func (oFsm *OnuUpgradeFsm) enterWaitEndDL(ctx context.Context, e *fsm.Event) {
+	logger.Infow(ctx, "OnuUpgradeFsm WaitEndDl", log.Fields{
+		"device-id": oFsm.deviceID, "wait delay": oFsm.waitDelayEndSwDl * time.Second, "wait count": oFsm.waitCountEndSwDl})
+	if oFsm.waitCountEndSwDl == 0 {
+		logger.Errorw(ctx, "WaitEndDl abort: max limit of EndSwDL reached", log.Fields{
+			"device-id": oFsm.deviceID})
+		pBaseFsm := oFsm.PAdaptFsm
+		if pBaseFsm == nil {
+			logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
+				"device-id": oFsm.deviceID})
+			return
+		}
+		oFsm.mutexUpgradeParams.Lock()
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+		oFsm.volthaDownloadReason = voltha.ImageState_IMAGE_REFUSED_BY_ONU //something like 'END_DOWNLOAD_TIMEOUT' would be better (proto)
+		oFsm.mutexUpgradeParams.Unlock()
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+		}(pBaseFsm)
+		return
+	}
+
+	oFsm.waitCountEndSwDl--
+	select {
+	case <-time.After(oFsm.waitDelayEndSwDl * time.Second):
+		pBaseFsm := oFsm.PAdaptFsm
+		if pBaseFsm == nil {
+			logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
+				"device-id": oFsm.deviceID})
+			//FSM may be reset already from somewhere else, nothing we can do here anymore
+			return
+		}
+		//retry End SW DL
+		oFsm.mutexUpgradeParams.Lock()
+		oFsm.delayEndSwDl = false //no more extra delay for the request
+		oFsm.mutexUpgradeParams.Unlock()
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			_ = a_pAFsm.PFsm.Event(UpgradeEvContinueFinalize)
+		}(pBaseFsm)
+		return
+	case success := <-oFsm.chReceiveExpectedResponse:
+		logger.Debugw(ctx, "WaitEndDl stop  wait timer", log.Fields{"device-id": oFsm.deviceID})
+		pBaseFsm := oFsm.PAdaptFsm
+		if pBaseFsm == nil {
+			logger.Errorw(ctx, "WaitEndDl abort: BaseFsm invalid", log.Fields{
+				"device-id": oFsm.deviceID})
+			//FSM may be reset already from somewhere else, nothing we can do here anymore
+			return
+		}
+		if success {
+			//answer received with ready indication
+			//useAPIVersion43 may not conflict in concurrency in this state function
+			if oFsm.useAPIVersion43 { // newer API usage requires verification of downloaded image version
+				go func(a_pAFsm *cmn.AdapterFsm) {
+					_ = a_pAFsm.PFsm.Event(UpgradeEvCheckImageName)
+				}(pBaseFsm)
+			} else { // elder API usage does not support image version check -immediately consider download as successful
+				if oFsm.activateImage {
+					//immediate activation requested
+					go func(a_pAFsm *cmn.AdapterFsm) {
+						_ = a_pAFsm.PFsm.Event(UpgradeEvRequestActivate)
+					}(pBaseFsm)
+				} else {
+					//have to wait on explicit activation request
+					go func(a_pAFsm *cmn.AdapterFsm) {
+						_ = a_pAFsm.PFsm.Event(UpgradeEvWaitForActivate)
+					}(pBaseFsm)
+				}
+			}
+			return
+		}
+		//timer was aborted
+		oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+		return
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) enterCheckImageName(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm checking downloaded image name", log.Fields{
+		"device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
+	requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
+	meInstance, err := oFsm.pOmciCC.SendGetMe(log.WithSpanFromContext(context.Background(), ctx),
+		me.SoftwareImageClassID, oFsm.InactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.GetOmciTimeout(),
+		false, oFsm.PAdaptFsm.CommChan)
+	if err != nil {
+		logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
+			log.Fields{"device-id": oFsm.deviceID, "Error": err})
+		oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+		return
+	}
+	oFsm.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *OnuUpgradeFsm) enterActivateSw(ctx context.Context, e *fsm.Event) {
+	logger.Infow(ctx, "OnuUpgradeFsm activate SW", log.Fields{
+		"device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
+
+	err := oFsm.pOmciCC.SendActivateSoftware(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
+		oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID)
+	if err != nil {
+		logger.Errorw(ctx, "ActivateSw abort: can't send activate frame", log.Fields{
+			"device-id": oFsm.deviceID, "error": err})
+		oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_ACTIVATION_ABORTED)
+		return
+	}
+	oFsm.mutexUpgradeParams.Lock()
+	oFsm.volthaImageState = voltha.ImageState_IMAGE_ACTIVATING
+	oFsm.mutexUpgradeParams.Unlock()
+}
+
+func (oFsm *OnuUpgradeFsm) enterCommitSw(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm start commit SW", log.Fields{
+		"device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
+	//any abort request (also conditional) is still regarded as valid as the commit indication might not be possible to verify
+	// (which is a bit problematic as the ONU might already be in committed state,
+	// in this case (committing failed) always 'onuimage list' should be used to verify the real state (if ONU is reachable))
+	if activeImageID, err := oFsm.pDevEntry.GetActiveImageMeID(ctx); err == nil {
+		oFsm.mutexUpgradeParams.Lock()
+		if activeImageID == oFsm.InactiveImageMeID {
+			inactiveImageID := oFsm.InactiveImageMeID
+			logger.Infow(ctx, "OnuUpgradeFsm commit SW", log.Fields{
+				"device-id": oFsm.deviceID, "me-id": inactiveImageID}) //more efficient activeImageID with above check
+			oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTING
+			oFsm.mutexUpgradeParams.Unlock()
+			err := oFsm.pOmciCC.SendCommitSoftware(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
+				oFsm.PAdaptFsm.CommChan, inactiveImageID) //more efficient activeImageID with above check
+			if err != nil {
+				logger.Errorw(ctx, "CommitSw abort: can't send commit sw frame", log.Fields{
+					"device-id": oFsm.deviceID, "error": err})
+				oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+				return
+			}
+			return
+		}
+		oFsm.mutexUpgradeParams.Unlock()
+		logger.Errorw(ctx, "OnuUpgradeFsm active ImageId <> IdToCommit", log.Fields{
+			"device-id": oFsm.deviceID, "active ID": activeImageID, "to commit ID": oFsm.InactiveImageMeID})
+	} else {
+		logger.Errorw(ctx, "OnuUpgradeFsm can't commit, no valid active image", log.Fields{
+			"device-id": oFsm.deviceID})
+	}
+	oFsm.mutexUpgradeParams.Lock()
+	oFsm.conditionalCancelRequested = false //any lingering conditional cancelRequest is superseded by this error
+	oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+	oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
+	oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
+	oFsm.mutexUpgradeParams.Unlock()
+	//TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
+	pBaseFsm := oFsm.PAdaptFsm
+	// Can't call FSM Event directly, decoupling it
+	go func(a_pAFsm *cmn.AdapterFsm) {
+		_ = a_pAFsm.PFsm.Event(UpgradeEvAbort)
+	}(pBaseFsm)
+}
+
+func (oFsm *OnuUpgradeFsm) enterCheckCommitted(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm checking committed SW", log.Fields{
+		"device-id": oFsm.deviceID, "me-id": oFsm.InactiveImageMeID})
+	requestedAttributes := me.AttributeValueMap{"IsCommitted": 0, "IsActive": 0, "Version": ""}
+	meInstance, err := oFsm.pOmciCC.SendGetMe(log.WithSpanFromContext(context.Background(), ctx),
+		me.SoftwareImageClassID, oFsm.InactiveImageMeID, requestedAttributes, oFsm.pDeviceHandler.GetOmciTimeout(), false, oFsm.PAdaptFsm.CommChan)
+	if err != nil {
+		logger.Errorw(ctx, "OnuUpgradeFsm get Software Image ME result error",
+			log.Fields{"device-id": oFsm.deviceID, "Error": err})
+		oFsm.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+		return
+	}
+	oFsm.pLastTxMeInstance = meInstance
+}
+
+func (oFsm *OnuUpgradeFsm) enterResetting(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm resetting", log.Fields{"device-id": oFsm.deviceID})
+
+	// if the reset was conditionally requested
+	if oFsm.conditionalCancelRequested {
+		oFsm.mutexUpgradeParams.Lock()
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+		oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
+		oFsm.mutexUpgradeParams.Unlock()
+	}
+
+	// in case the download-to-ONU timer is still running - cancel it
+	//use non-blocking channel (to be independent from receiver state)
+	select {
+	//use channel to indicate that the download response waiting shall be aborted for this device (channel)
+	case oFsm.chOnuDlReady <- false:
+	default:
+	}
+	pConfigUpgradeStateAFsm := oFsm.PAdaptFsm
+	if pConfigUpgradeStateAFsm != nil {
+		var nextEvent string
+		if oFsm.isEndSwDlOpen {
+			nextEvent = UpgradeEvAbortSwDownload
+		} else {
+			nextEvent = UpgradeEvRestart
+		}
+		// Can't call FSM Event directly, decoupling it
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(nextEvent)
+			}
+		}(pConfigUpgradeStateAFsm)
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) enterAbortingDL(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm aborting download to ONU", log.Fields{"device-id": oFsm.deviceID})
+
+	pBaseFsm := oFsm.PAdaptFsm
+	if pBaseFsm == nil {
+		logger.Errorw(ctx, "OnuUpgradeFsm aborting download: BaseFsm invalid", log.Fields{"device-id": oFsm.deviceID})
+		return
+	}
+	// abort the download operation by sending an end software download message with invalid CRC and image size
+	err := oFsm.pOmciCC.SendEndSoftwareDownload(log.WithSpanFromContext(context.Background(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), false,
+		oFsm.PAdaptFsm.CommChan, oFsm.InactiveImageMeID, 0, 0xFFFFFFFF)
+
+	oFsm.isEndSwDlOpen = false // also to be reset in case of OMCI error, as further send attempts would not make sense
+
+	if err != nil {
+		logger.Errorw(ctx, "OnuUpgradeFsm aborting download: can't send EndSwDl request", log.Fields{"device-id": oFsm.deviceID})
+		// Can't call FSM Event directly, decoupling it
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvRestart)
+			}
+		}(pBaseFsm)
+		return
+	}
+	select {
+	case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
+		logger.Warnw(ctx, "OnuUpgradeFsm aborting download: timeout - no response received", log.Fields{"device-id": oFsm.deviceID})
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvRestart)
+			}
+		}(pBaseFsm)
+		return
+	case <-oFsm.chReceiveAbortEndSwDlResponse:
+		logger.Debug(ctx, "OnuUpgradeFsm aborting download: response received")
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvRestart)
+			}
+		}(pBaseFsm)
+		return
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) enterRestarting(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm restarting", log.Fields{"device-id": oFsm.deviceID})
+	pConfigUpgradeStateAFsm := oFsm.PAdaptFsm
+	if pConfigUpgradeStateAFsm != nil {
+		// abort running message processing
+		fsmAbortMsg := cmn.Message{
+			Type: cmn.TestMsg,
+			Data: cmn.TestMessage{
+				TestMessageVal: cmn.AbortMessageProcessing,
+			},
+		}
+		pConfigUpgradeStateAFsm.CommChan <- fsmAbortMsg
+
+		//try to restart the FSM to 'disabled'
+		// Can't call FSM Event directly, decoupling it
+		go func(a_pAFsm *cmn.AdapterFsm) {
+			if a_pAFsm != nil && a_pAFsm.PFsm != nil {
+				_ = a_pAFsm.PFsm.Event(UpgradeEvDisable)
+			}
+		}(pConfigUpgradeStateAFsm)
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
+	logger.Debugw(ctx, "OnuUpgradeFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
+	// no need to flush possible channels here, Upgrade FSM will be completely removed, garbage collector should find its way
+	if oFsm.pDeviceHandler != nil {
+		//request removal of 'reference' in the Handler (completely clear the FSM and its data)
+		pLastUpgradeImageState := &voltha.ImageState{
+			Version:       oFsm.imageVersion,
+			DownloadState: oFsm.volthaDownloadState,
+			Reason:        oFsm.volthaDownloadReason,
+			ImageState:    oFsm.volthaImageState,
+		}
+		go oFsm.pDeviceHandler.RemoveOnuUpgradeFsm(ctx, pLastUpgradeImageState)
+	}
+}
+
+func (oFsm *OnuUpgradeFsm) processOmciUpgradeMessages(ctx context.Context) { //ctx context.Context?
+	logger.Debugw(ctx, "Start OnuUpgradeFsm 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, "OnuUpgradeFsm 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.abortOnOmciError(ctx, true, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+			break loop
+		}
+		logger.Debugw(ctx, "OnuUpgradeFsm 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.Infow(ctx, "OnuUpgradeFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
+				break loop
+			}
+			logger.Warnw(ctx, "OnuUpgradeFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
+		case cmn.OMCI:
+			msg, _ := message.Data.(cmn.OmciMessage)
+			oFsm.handleOmciOnuUpgradeMessage(ctx, msg)
+		default:
+			logger.Warn(ctx, "OnuUpgradeFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
+				"message.Type": message.Type})
+		}
+	}
+	logger.Infow(ctx, "End OnuUpgradeFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
+}
+
+//nolint: gocyclo
+func (oFsm *OnuUpgradeFsm) handleOmciOnuUpgradeMessage(ctx context.Context, msg cmn.OmciMessage) {
+	logger.Debugw(ctx, "Rx OMCI OnuUpgradeFsm Msg", log.Fields{"device-id": oFsm.deviceID,
+		"msgType": msg.OmciMsg.MessageType})
+
+	switch msg.OmciMsg.MessageType {
+	case omci.StartSoftwareDownloadResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeStartSoftwareDownloadResponse)
+			if msgLayer == nil {
+				logger.Errorw(ctx, "Omci Msg layer could not be detected for StartSwDlResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadResponse)
+			if !msgOk {
+				logger.Errorw(ctx, "Omci Msg layer could not be assigned for StartSwDlResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			logger.Debugw(ctx, "OnuUpgradeFsm StartSwDlResponse data", log.Fields{
+				"device-id": oFsm.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse result error - later: drive FSM to abort state ?",
+					log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+
+			oFsm.mutexUpgradeParams.Lock()
+			if msgObj.EntityInstance == oFsm.InactiveImageMeID {
+				logger.Debugw(ctx, "Expected StartSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
+				if msgObj.WindowSize != oFsm.omciDownloadWindowSizeLimit {
+					// also response WindowSize = 0 is a valid number for used Window size 1
+					logger.Debugw(ctx, "different StartSwDlResponse window size requested by ONU", log.Fields{
+						"acceptedOnuWindowSizeLimit": msgObj.WindowSize, "device-id": oFsm.deviceID})
+					oFsm.omciDownloadWindowSizeLimit = msgObj.WindowSize
+				}
+				oFsm.noOfWindows = oFsm.noOfSections / uint32(oFsm.omciDownloadWindowSizeLimit+1)
+				if oFsm.noOfSections%uint32(oFsm.omciDownloadWindowSizeLimit+1) > 0 {
+					oFsm.noOfWindows++
+				}
+				logger.Debugw(ctx, "OnuUpgradeFsm will use", log.Fields{
+					"windows": oFsm.noOfWindows, "sections": oFsm.noOfSections,
+					"at WindowSizeLimit": oFsm.omciDownloadWindowSizeLimit})
+				oFsm.nextDownloadSectionsAbsolute = 0
+				oFsm.nextDownloadSectionsWindow = 0
+				oFsm.nextDownloadWindow = 0
+
+				oFsm.mutexUpgradeParams.Unlock()
+				_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvRxStartSwDownload)
+				return
+			}
+			oFsm.mutexUpgradeParams.Unlock()
+			logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
+				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+			oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+			return
+		} //StartSoftwareDownloadResponseType
+	case omci.DownloadSectionResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeDownloadSectionResponse)
+			if msgLayer == nil {
+				logger.Errorw(ctx, "Omci Msg layer could not be detected for DlSectionResponse",
+					log.Fields{"device-id": oFsm.deviceID, "omci-message": msg.OmciMsg})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.DownloadSectionResponse)
+			if !msgOk {
+				logger.Errorw(ctx, "Omci Msg layer could not be assigned for DlSectionResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			logger.Debugw(ctx, "OnuUpgradeFsm DlSectionResponse Data", log.Fields{
+				"device-id": oFsm.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse result error - later: repeat window once?", //TODO!!!
+					log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			oFsm.mutexUpgradeParams.Lock()
+			if msgObj.EntityInstance == oFsm.InactiveImageMeID {
+				sectionNumber := msgObj.SectionNumber
+				logger.Infow(ctx, "DlSectionResponse received", log.Fields{
+					"window section-number": sectionNumber, "window": oFsm.nextDownloadWindow, "device-id": oFsm.deviceID})
+
+				oFsm.nextDownloadWindow++
+				if oFsm.nextDownloadWindow >= oFsm.noOfWindows {
+					if sectionNumber != oFsm.omciDownloadWindowSizeLast {
+						logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error last window - later: repeat window once?", //TODO!!!
+							log.Fields{"device-id": oFsm.deviceID, "actual section": sectionNumber,
+								"expected section": oFsm.omciDownloadWindowSizeLast})
+						oFsm.mutexUpgradeParams.Unlock()
+						oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+						return
+					}
+					oFsm.delayEndSwDl = true //ensure a delay for the EndSwDl message
+					//CRC computation for all data bytes of the file
+					imageCRC := crc32a.Checksum(oFsm.imageBuffer[:int(oFsm.origImageLength)]) //store internal for multiple usage
+					//revert the retrieved CRC Byte Order (seems not to deliver NetworkByteOrder)
+					var byteSlice []byte = make([]byte, 4)
+					binary.LittleEndian.PutUint32(byteSlice, uint32(imageCRC))
+					oFsm.imageCRC = binary.BigEndian.Uint32(byteSlice)
+					oFsm.mutexUpgradeParams.Unlock()
+					_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvEndSwDownload)
+					return
+				}
+				if sectionNumber != oFsm.omciDownloadWindowSizeLimit {
+					logger.Errorw(ctx, "OnuUpgradeFsm DlSectionResponse section error - later: repeat window once?", //TODO!!!
+						log.Fields{"device-id": oFsm.deviceID, "actual-section": sectionNumber,
+							"expected section": oFsm.omciDownloadWindowSizeLimit})
+					oFsm.mutexUpgradeParams.Unlock()
+					oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+					return
+				}
+				oFsm.nextDownloadSectionsWindow = 0
+				oFsm.mutexUpgradeParams.Unlock()
+				_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvContinueNextWindow)
+				return
+			}
+			oFsm.mutexUpgradeParams.Unlock()
+			logger.Errorw(ctx, "OnuUpgradeFsm Omci StartSwDlResponse wrong ME instance: try again (later)?",
+				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+			oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+			return
+		} //DownloadSectionResponseType
+	case omci.EndSoftwareDownloadResponseType:
+		{
+			if oFsm.PAdaptFsm.PFsm.Is(UpgradeStAbortingDL) {
+				// calling FSM events in background to avoid blocking of the caller
+				go func(aPAFsm *cmn.AdapterFsm) {
+					oFsm.chReceiveAbortEndSwDlResponse <- true
+				}(oFsm.PAdaptFsm)
+				return
+			}
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeEndSoftwareDownloadResponse)
+			if msgLayer == nil {
+				logger.Errorw(ctx, "Omci Msg layer could not be detected for EndSwDlResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadResponse)
+			if !msgOk {
+				logger.Errorw(ctx, "Omci Msg layer could not be assigned for EndSwDlResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse data", log.Fields{
+				"device-id": oFsm.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				if msgObj.Result == me.DeviceBusy {
+					//ONU indicates it is still processing the image - let the FSM just wait and then repeat the request
+					logger.Debugw(ctx, "OnuUpgradeFsm EndSwDlResponse busy: waiting before sending new request", log.Fields{
+						"device-id": oFsm.deviceID})
+					return
+				}
+				logger.Errorw(ctx, "OnuUpgradeFsm EndSwDlResponse result error - later: drive FSM to abort state ?",
+					log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+				return
+			}
+			oFsm.mutexUpgradeParams.Lock()
+			if msgObj.EntityInstance == oFsm.InactiveImageMeID {
+				//EndSwDownloadSuccess is used to indicate 'DOWNLOAD_SUCCEEDED'
+				oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
+				if !oFsm.useAPIVersion43 {
+					//in the older API version the image version check was not possible
+					//  - assume new loaded image as valid-inactive immediately
+					oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
+					oFsm.mutexUpgradeParams.Unlock()
+					//use non-blocking channel (to be independent from receiver state)
+					select {
+					//use non-blocking channel to indicate that the download to ONU was successful
+					case oFsm.chOnuDlReady <- true:
+					default:
+					}
+				} else {
+					oFsm.mutexUpgradeParams.Unlock()
+				}
+				logger.Debugw(ctx, "Expected EndSwDlResponse received", log.Fields{"device-id": oFsm.deviceID})
+				//use non-blocking channel to let the FSM proceed from the waitState
+				select {
+				case oFsm.chReceiveExpectedResponse <- true:
+				default:
+				}
+				return
+			}
+			oFsm.mutexUpgradeParams.Unlock()
+			logger.Errorw(ctx, "OnuUpgradeFsm StartSwDlResponse wrong ME instance: try again (later)?",
+				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+			oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_DOWNLOADING)
+			return
+		} //EndSoftwareDownloadResponseType
+	case omci.ActivateSoftwareResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeActivateSoftwareResponse)
+			if msgLayer == nil {
+				logger.Errorw(ctx, "Omci Msg layer could not be detected for ActivateSw",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_ACTIVATION_ABORTED)
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareResponse)
+			if !msgOk {
+				logger.Errorw(ctx, "Omci Msg layer could not be assigned for ActivateSw",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_ACTIVATION_ABORTED)
+				return
+			}
+			logger.Debugw(ctx, "OnuUpgradeFsm ActivateSwResponse data", log.Fields{
+				"device-id": oFsm.deviceID, "data-fields": msgObj})
+			if msgObj.Result != me.Success {
+				logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse result error - later: drive FSM to abort state ?",
+					log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_ACTIVATION_ABORTED)
+				return
+			}
+			oFsm.mutexUpgradeParams.Lock()
+			if msgObj.EntityInstance == oFsm.InactiveImageMeID {
+				// the image is regarded as active really only after ONU reboot and according indication (ONU down/up procedure)
+				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.Unlock()
+			logger.Errorw(ctx, "OnuUpgradeFsm ActivateSwResponse wrong ME instance: abort",
+				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+			oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_ACTIVATION_ABORTED)
+			return
+		} //ActivateSoftwareResponseType
+	case omci.CommitSoftwareResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeCommitSoftwareResponse)
+			if msgLayer == nil {
+				logger.Errorw(ctx, "Omci Msg layer could not be detected for CommitResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.CommitSoftwareResponse)
+			if !msgOk {
+				logger.Errorw(ctx, "Omci Msg layer could not be assigned for CommitResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+				return
+			}
+			if msgObj.Result != me.Success {
+				logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse result error - later: drive FSM to abort state ?",
+					log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+				return
+			}
+			oFsm.mutexUpgradeParams.RLock()
+			if msgObj.EntityInstance == oFsm.InactiveImageMeID {
+				oFsm.mutexUpgradeParams.RUnlock()
+				logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
+				//verifying committed image
+				_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvCheckCommitted)
+				return
+			}
+			oFsm.mutexUpgradeParams.RUnlock()
+			logger.Errorw(ctx, "OnuUpgradeFsm SwImage CommitResponse  wrong ME instance: abort",
+				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+			oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+			return
+		} //CommitSoftwareResponseType
+	case omci.GetResponseType:
+		{
+			msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
+			if msgLayer == nil {
+				logger.Errorw(ctx, "Omci Msg layer could not be detected for SwImage GetResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+				return
+			}
+			msgObj, msgOk := msgLayer.(*omci.GetResponse)
+			if !msgOk {
+				logger.Errorw(ctx, "Omci Msg layer could not be assigned for SwImage GetResponse",
+					log.Fields{"device-id": oFsm.deviceID})
+				oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+				return
+			}
+			logger.Debugw(ctx, "OnuUpgradeFsm SwImage GetResponse data", log.Fields{
+				"device-id": oFsm.deviceID, "data-fields": msgObj})
+			if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
+				msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
+				if msgObj.Result != me.Success {
+					logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse result error - later: drive FSM to abort state ?",
+						log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
+					oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_COMMIT_ABORTED)
+					return
+				}
+			} else {
+				logger.Warnw(ctx, "OnuUpgradeFsm SwImage unexpected Entity GetResponse data - ignore",
+					log.Fields{"device-id": oFsm.deviceID})
+				return
+			}
+
+			meAttributes := msgObj.Attributes
+			imageIsCommitted := meAttributes["IsCommitted"].(uint8)
+			imageIsActive := meAttributes["IsActive"].(uint8)
+			imageVersion := cmn.TrimStringFromMeOctet(meAttributes["Version"])
+			logger.Debugw(ctx, "OnuUpgradeFsm - GetResponse Data for SoftwareImage",
+				log.Fields{"device-id": oFsm.deviceID, "entityID": msgObj.EntityInstance,
+					"version": imageVersion, "isActive": imageIsActive, "isCommitted": imageIsCommitted})
+
+			if oFsm.PAdaptFsm.PFsm.Current() == UpgradeStCheckImageName {
+				//image name check after EndSwDownload, this state (and block) can only be taken if APIVersion43 is used
+				oFsm.mutexUpgradeParams.Lock()
+				if msgObj.EntityInstance == oFsm.InactiveImageMeID && imageIsActive == cmn.SwIsInactive &&
+					imageIsCommitted == cmn.SwIsUncommitted {
+					if imageVersion != oFsm.imageVersion {
+						//new stored inactive version indicated on OMCI from ONU is not the expected version
+						logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse version indication not matching requested upgrade",
+							log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance,
+								"onu-version": imageVersion, "expected-version": oFsm.imageVersion})
+						oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED         //not the expected image was downloaded
+						oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE //something like 'UNEXPECTED_VERSION' would be better - proto def
+						oFsm.volthaImageState = voltha.ImageState_IMAGE_UNKNOWN              //something like 'DOWNLOADED' would be better - proto def
+						oFsm.mutexUpgradeParams.Unlock()
+						//stop the running ONU download timer
+						//use non-blocking channel (to be independent from receiver state)
+						select {
+						//use channel to indicate that the download response waiting shall be aborted for this device (channel)
+						case oFsm.chOnuDlReady <- false:
+						default:
+						}
+						// TODO!!!: error treatment?
+						//TODO!!!: possibly send event information for aborted upgrade (aborted by wrong version)?
+						_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+						return
+					}
+					//with APIVersion43 this is the point to consider the newly loaded image as valid (and inactive)
+					oFsm.volthaImageState = voltha.ImageState_IMAGE_INACTIVE
+					//store the new inactive version to onuSwImageIndications (to keep them in sync)
+					oFsm.pDevEntry.ModifySwImageInactiveVersion(ctx, oFsm.imageVersion)
+					//proceed within upgrade FSM
+					if oFsm.activateImage {
+						//immediate activation requested
+						oFsm.mutexUpgradeParams.Unlock()
+						logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU, continue with activation",
+							log.Fields{"device-id": oFsm.deviceID})
+						_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvRequestActivate)
+					} else {
+						//have to wait on explicit activation request
+						// but a previously requested download activity (without activation) was successful here
+						oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
+						oFsm.mutexUpgradeParams.Unlock()
+						logger.Infow(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU, wait for activate request",
+							log.Fields{"device-id": oFsm.deviceID})
+						_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvWaitForActivate)
+					}
+					//use non-blocking channel (to be independent from receiver state)
+					select {
+					//use non-blocking channel to indicate that the download to ONU was successful
+					case oFsm.chOnuDlReady <- true:
+					default:
+					}
+					return
+				}
+				//not the expected image/image state
+				oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+				oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
+				oFsm.volthaImageState = voltha.ImageState_IMAGE_UNKNOWN //real image state not known
+				oFsm.mutexUpgradeParams.Unlock()
+				logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
+					log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+				// TODO!!!: error treatment?
+				//TODO!!!: possibly send event information for aborted upgrade (aborted by ONU state indication)?
+				_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+				return
+			}
+
+			//assumed only relevant state here is UpgradeStCheckCommitted
+			oFsm.mutexUpgradeParams.Lock()
+			oFsm.conditionalCancelRequested = false //getting here any set (conditional) cancelRequest is not relevant anymore
+			if msgObj.EntityInstance == oFsm.InactiveImageMeID && imageIsActive == cmn.SwIsActive {
+				//a check on the delivered image version is not done, the ONU delivered version might be different from what might have been
+				//  indicated in the download image version string (version must be part of the image content itself)
+				//  so checking that might be quite unreliable
+				//but with new API this was changed, assumption is that omci image version is known at download request and exactly that is used
+				//  in all the API references, so it can and should be checked here now
+				if oFsm.useAPIVersion43 {
+					if imageVersion != oFsm.imageVersion {
+						//new active version indicated on OMCI from ONU is not the expected version
+						logger.Errorw(ctx, "OnuUpgradeFsm image-version not matching the requested upgrade",
+							log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance,
+								"onu-version": imageVersion, "expected-version": oFsm.imageVersion})
+						// TODO!!!: error treatment?
+						//TODO!!!: possibly send event information for aborted upgrade (aborted by wrong version)?
+						oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED         //not the expected image was committed
+						oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE //something like 'UNEXPECTED_VERSION' would be better - proto def
+						oFsm.volthaImageState = voltha.ImageState_IMAGE_UNKNOWN              //expected image not known
+						oFsm.mutexUpgradeParams.Unlock()
+						_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+						return
+					}
+					logger.Debugw(ctx, "OnuUpgradeFsm - expected ONU image version indicated by the ONU",
+						log.Fields{"device-id": oFsm.deviceID})
+				}
+				if imageIsCommitted == cmn.SwIsCommitted {
+					oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
+					oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMITTED
+					//store the new commit flag to onuSwImageIndications (to keep them in sync)
+					oFsm.pDevEntry.ModifySwImageActiveCommit(ctx, imageIsCommitted)
+					logger.Infow(ctx, "requested SW image committed, releasing OnuUpgrade", log.Fields{"device-id": oFsm.deviceID})
+					//deviceProcStatusUpdate not used anymore,
+					// replaced by transferring the last (more) upgrade state information within RemoveOnuUpgradeFsm
+					oFsm.mutexUpgradeParams.Unlock()
+					//releasing the upgrade FSM on success
+					_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+					return
+				}
+				//if not committed, abort upgrade as failed. There is no implementation here that would trigger this test again
+			}
+			oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+			oFsm.volthaDownloadReason = voltha.ImageState_CANCELLED_ON_ONU_STATE
+			oFsm.volthaImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
+			oFsm.mutexUpgradeParams.Unlock()
+			logger.Errorw(ctx, "OnuUpgradeFsm SwImage GetResponse indications not matching requested upgrade",
+				log.Fields{"device-id": oFsm.deviceID, "ResponseMeId": msgObj.EntityInstance})
+			// TODO!!!: error treatment?
+			//TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
+			_ = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+			return
+		} //GetResponseType
+	default:
+		{
+			logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
+				log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
+			return
+		}
+	}
+}
+
+//abortOnOmciError aborts the upgrade processing with OMCI_TRANSFER_ERROR indication
+func (oFsm *OnuUpgradeFsm) abortOnOmciError(ctx context.Context, aAsync bool,
+	aImageState voltha.ImageState_ImageActivationState) {
+	oFsm.mutexUpgradeParams.Lock()
+	oFsm.conditionalCancelRequested = false //any conditional cancelRequest is superseded by this abortion
+	oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+	oFsm.volthaDownloadReason = voltha.ImageState_OMCI_TRANSFER_ERROR
+	if aImageState != voltha.ImageState_IMAGE_UNKNOWN {
+		// update image state only in case some explicite state is given (otherwise the existing state is used)
+		oFsm.volthaImageState = aImageState
+	}
+	oFsm.mutexUpgradeParams.Unlock()
+	//TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
+	if oFsm.PAdaptFsm != nil {
+		var err error
+		if aAsync { //asynchronous call requested to ensure state transition
+			go func(a_pAFsm *cmn.AdapterFsm) {
+				if a_pAFsm.PFsm != nil {
+					err = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+				}
+			}(oFsm.PAdaptFsm)
+		} else {
+			if oFsm.PAdaptFsm.PFsm != nil {
+				err = oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+			}
+		}
+		if err != nil {
+			logger.Warnw(ctx, "onu upgrade fsm could not abort on omci error", log.Fields{
+				"device-id": oFsm.deviceID, "error": err})
+		}
+	}
+}
+
+//waitOnDownloadToAdapterReady state can only be reached with useAPIVersion43 (usage of pFileManager)
+//  precondition: mutexIsAwaitingAdapterDlResponse is lockek on call
+func (oFsm *OnuUpgradeFsm) waitOnDownloadToAdapterReady(ctx context.Context, aSyncChannel chan<- struct{},
+	aWaitChannel chan bool) {
+	oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
+	downloadToAdapterTimeout := oFsm.pFileManager.GetDownloadTimeout(ctx)
+	oFsm.isWaitingForAdapterDlResponse = true
+	oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
+	aSyncChannel <- struct{}{}
+	select {
+	// maybe be also some outside cancel (but no context modeled for the moment ...)
+	// case <-ctx.Done():
+	// 		logger.Infow("OnuUpgradeFsm-waitOnDownloadToAdapterReady canceled", log.Fields{"for device-id": oFsm.deviceID})
+	case <-time.After(downloadToAdapterTimeout): //10s should be enough for downloading some image to the adapter
+		logger.Warnw(ctx, "OnuUpgradeFsm Waiting-adapter-download timeout", log.Fields{
+			"for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToAdapterTimeout})
+		oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
+		//running into timeout here may still have the download to adapter active -> abort
+		oFsm.pFileManager.CancelDownload(ctx, oFsm.imageIdentifier)
+		oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
+		oFsm.isWaitingForAdapterDlResponse = false
+		oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
+		oFsm.mutexUpgradeParams.Lock()
+		oFsm.conditionalCancelRequested = false //any conditional cancelRequest is superseded by this abortion
+		oFsm.volthaDownloadState = voltha.ImageState_DOWNLOAD_FAILED
+		oFsm.volthaDownloadReason = voltha.ImageState_UNKNOWN_ERROR //something like 'DOWNLOAD_TO_ADAPTER_TIMEOUT' would be better (proto)
+		oFsm.volthaImageState = voltha.ImageState_IMAGE_UNKNOWN     //something like 'IMAGE_DOWNLOAD_ABORTED' would be better (proto)
+		oFsm.mutexUpgradeParams.Unlock()
+		//TODO!!!: possibly send event information for aborted upgrade (aborted by omci processing)??
+		if oFsm.PAdaptFsm != nil && oFsm.PAdaptFsm.PFsm != nil {
+			err := oFsm.PAdaptFsm.PFsm.Event(UpgradeEvAbort)
+			if err != nil {
+				logger.Warnw(ctx, "onu upgrade fsm could not abort on omci error", log.Fields{
+					"device-id": oFsm.deviceID, "error": err})
+			}
+		}
+		return
+
+	case success := <-aWaitChannel:
+		if success {
+			logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded received", log.Fields{"device-id": oFsm.deviceID})
+			oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
+			oFsm.isWaitingForAdapterDlResponse = false
+			oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
+			//let the upgrade process proceed
+			pUpgradeFsm := oFsm.PAdaptFsm
+			if pUpgradeFsm != nil {
+				_ = pUpgradeFsm.PFsm.Event(UpgradeEvPrepareSwDownload)
+			} else {
+				logger.Errorw(ctx, "pUpgradeFsm is nil", log.Fields{"device-id": oFsm.deviceID})
+			}
+			return
+		}
+		// waiting was aborted (assumed here to be caused by
+		//   error detection or cancel at download after upgrade FSM reset/abort with according image states set there)
+		logger.Debugw(ctx, "OnuUpgradeFsm Waiting-adapter-download aborted", log.Fields{"device-id": oFsm.deviceID})
+		oFsm.pFileManager.RemoveReadyRequest(ctx, oFsm.imageIdentifier, aWaitChannel)
+		oFsm.mutexIsAwaitingAdapterDlResponse.Lock()
+		oFsm.isWaitingForAdapterDlResponse = false
+		oFsm.mutexIsAwaitingAdapterDlResponse.Unlock()
+		return
+	}
+}
+
+//waitOnDownloadToOnuReady state can only be reached with useAPIVersion43 (usage of pFileManager)
+func (oFsm *OnuUpgradeFsm) waitOnDownloadToOnuReady(ctx context.Context, aWaitChannel chan bool) {
+	downloadToOnuTimeout := time.Duration(1+(oFsm.imageLength/0x400000)) * oFsm.downloadToOnuTimeout4MB
+	logger.Debugw(ctx, "OnuUpgradeFsm start download-to-ONU timer", log.Fields{"device-id": oFsm.deviceID,
+		"duration": downloadToOnuTimeout})
+	select {
+	// maybe be also some outside cancel (but no context modeled for the moment ...)
+	// case <-ctx.Done():
+	// 		logger.Infow("OnuUpgradeFsm-waitOnDownloadToOnuReady canceled", log.Fields{"for device-id": oFsm.deviceID})
+	case <-time.After(downloadToOnuTimeout): //using an image-size depending timout (in minutes)
+		logger.Warnw(ctx, "OnuUpgradeFsm Waiting-ONU-download timeout", log.Fields{
+			"for device-id": oFsm.deviceID, "image-id": oFsm.imageIdentifier, "timeout": downloadToOnuTimeout})
+		//the upgrade process has to be aborted
+		oFsm.abortOnOmciError(ctx, false, voltha.ImageState_IMAGE_UNKNOWN) //no ImageState update
+		return
+
+	case success := <-aWaitChannel:
+		if success {
+			logger.Debugw(ctx, "OnuUpgradeFsm image-downloaded on ONU received", log.Fields{"device-id": oFsm.deviceID})
+			//all fine, let the FSM proceed like defined from the sender of this event
+			return
+		}
+		// waiting was aborted (assumed here to be caused by
+		//   error detection or cancel at download after upgrade FSM reset/abort with according image states set there)
+		logger.Debugw(ctx, "OnuUpgradeFsm Waiting-ONU-download aborted", log.Fields{"device-id": oFsm.deviceID})
+		return
+	}
+}
diff --git a/internal/pkg/swupg/onu_image_status.go b/internal/pkg/swupg/onu_image_status.go
new file mode 100755
index 0000000..4e1215f
--- /dev/null
+++ b/internal/pkg/swupg/onu_image_status.go
@@ -0,0 +1,361 @@
+/*
+ * 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 swupg provides the utilities for onu sw upgrade
+package swupg
+
+import (
+	"context"
+	"encoding/hex"
+	"fmt"
+	"sync"
+	"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/voltha"
+)
+
+//OnuImageStatus implements methods to get status info of onu images
+type OnuImageStatus struct {
+	deviceID               string
+	pDeviceHandler         cmn.IdeviceHandler
+	pDevEntry              cmn.IonuDeviceEntry
+	pOmciCC                *cmn.OmciCC
+	requestedAttributes    me.AttributeValueMap
+	mutexWaitingForResp    sync.RWMutex
+	waitingForResp         bool
+	respChannel            chan cmn.Message
+	mutexPLastTxMeInstance sync.RWMutex
+	pLastTxMeInstance      *me.ManagedEntity
+}
+
+const (
+	cImgVersion     = "Version"
+	cImgIsCommitted = "IsCommitted"
+	cImgIsActive    = "IsActive"
+	cImgIsValid     = "IsValid"
+	cImgProductCode = "ProductCode"
+	cImgImageHash   = "ImageHash"
+)
+const cResponse = "response: "
+
+//NewOnuImageStatus creates a new instance of OnuImageStatus
+func NewOnuImageStatus(apDeviceHandler cmn.IdeviceHandler, apDevEntry cmn.IonuDeviceEntry) *OnuImageStatus {
+	return &OnuImageStatus{
+		deviceID:            apDeviceHandler.GetDeviceID(),
+		pDeviceHandler:      apDeviceHandler,
+		pDevEntry:           apDevEntry,
+		pOmciCC:             apDevEntry.GetDevOmciCC(),
+		requestedAttributes: make(me.AttributeValueMap),
+		waitingForResp:      false,
+		respChannel:         make(chan cmn.Message),
+	}
+}
+
+// GetOnuImageStatus - TODO: add comment
+func (oo *OnuImageStatus) GetOnuImageStatus(ctx context.Context) (*voltha.OnuImages, error) {
+
+	if !oo.pDeviceHandler.IsReadyForOmciConfig() {
+		logger.Errorw(ctx, "command rejected - improper device state", log.Fields{"device-id": oo.deviceID})
+		return nil, fmt.Errorf("command-rejected-improper-device-state")
+	}
+	if oo.pOmciCC == nil {
+		logger.Errorw(ctx, "omciCC not ready to receive omci messages", log.Fields{"device-id": oo.deviceID})
+		return nil, fmt.Errorf("omciCC-not-ready-to-receive-omci-messages")
+	}
+	var images voltha.OnuImages
+
+	for i := cmn.FirstSwImageMeID; i <= cmn.SecondSwImageMeID; i++ {
+		logger.Debugw(ctx, "GetOnuImageStatus for image id", log.Fields{"image-id": i, "device-id": oo.deviceID})
+
+		var image voltha.OnuImage
+
+		// TODO: Since the summed length of the attributes exceeds the capacity of a single response,
+		// it is distributed on several requests here. It should be discussed whether, in the course of a refactoring,
+		// a global mechanism should be implemented that automates this distribution - which would entail quite some
+		// changes on the respective receiver sides.
+
+		oo.requestedAttributes = me.AttributeValueMap{cImgVersion: "", cImgIsCommitted: 0, cImgIsActive: 0, cImgIsValid: 0}
+		if err := oo.requestOnuImageAttributes(ctx, uint16(i), &image); err != nil {
+			logger.Errorw(ctx, err.Error(), log.Fields{"requestedAttributes": oo.requestedAttributes, "device-id": oo.deviceID})
+			return nil, err
+		}
+		oo.requestedAttributes = me.AttributeValueMap{cImgProductCode: ""}
+		if err := oo.requestOnuImageAttributes(ctx, uint16(i), &image); err != nil {
+			logger.Errorw(ctx, err.Error(), log.Fields{"requestedAttributes": oo.requestedAttributes, "device-id": oo.deviceID})
+			return nil, err
+		}
+		oo.requestedAttributes = me.AttributeValueMap{cImgImageHash: 0}
+		if err := oo.requestOnuImageAttributes(ctx, uint16(i), &image); err != nil {
+			logger.Errorw(ctx, err.Error(), log.Fields{"requestedAttributes": oo.requestedAttributes, "device-id": oo.deviceID})
+			return nil, err
+		}
+		images.Items = append(images.Items, &image)
+	}
+	logger.Debugw(ctx, "images of the ONU", log.Fields{"images": images})
+	oo.updateOnuSwImageIndications(ctx, &images)
+	oo.updateOnuSwImagePersistentData(ctx)
+	return &images, nil
+}
+
+func (oo *OnuImageStatus) requestOnuImageAttributes(ctx context.Context, imageID uint16, image *voltha.OnuImage) error {
+	oo.mutexPLastTxMeInstance.Lock()
+	meInstance, err := oo.pOmciCC.SendGetMe(log.WithSpanFromContext(context.TODO(), ctx), me.SoftwareImageClassID,
+		imageID, oo.requestedAttributes, oo.pDeviceHandler.GetOmciTimeout(), true, oo.respChannel)
+	if err != nil {
+		oo.mutexPLastTxMeInstance.Unlock()
+		logger.Errorw(ctx, "can't send omci request to get data for image id", log.Fields{"image-id": imageID, "device-id": oo.deviceID})
+		return fmt.Errorf("can't-send-omci-request-to-get-data-for-image-id-%d", imageID)
+	}
+	oo.pLastTxMeInstance = meInstance
+	oo.mutexPLastTxMeInstance.Unlock()
+
+	if err = oo.waitForGetOnuImageStatus(ctx, image); err != nil {
+		logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oo.deviceID})
+		return err
+	}
+	return nil
+}
+
+func (oo *OnuImageStatus) waitForGetOnuImageStatus(ctx context.Context, image *voltha.OnuImage) error {
+	oo.setWaitingForResp(true)
+	select {
+	// maybe be also some outside cancel (but no context modeled for the moment ...)
+	case <-ctx.Done():
+		logger.Errorw(ctx, "waitForGetOnuImageStatus context done", log.Fields{"device-id": oo.deviceID})
+		oo.setWaitingForResp(false)
+		return fmt.Errorf("wait-for-image-status-context-done")
+	case <-time.After(oo.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
+		logger.Errorw(ctx, "waitForGetOnuImageStatus timeout", log.Fields{"device-id": oo.deviceID})
+		oo.setWaitingForResp(false)
+		return fmt.Errorf("wait-for-image-status-timeout")
+	case message, ok := <-oo.respChannel:
+		if !ok {
+			logger.Errorw(ctx, "waitForGetOnuImageStatus response error", log.Fields{"device-id": oo.deviceID})
+			oo.setWaitingForResp(false)
+			return fmt.Errorf("wait-for-image-status-response-error")
+		}
+		switch message.Type {
+		case cmn.OMCI:
+			msg, _ := message.Data.(cmn.OmciMessage)
+			oo.setWaitingForResp(false)
+			return oo.processGetOnuImageStatusResp(ctx, msg, image)
+		case cmn.TestMsg:
+			msg, _ := message.Data.(cmn.TestMessage)
+			if msg.TestMessageVal == cmn.AbortMessageProcessing {
+				logger.Info(ctx, "waitForGetOnuImageStatus abort msg received", log.Fields{"device-id": oo.deviceID})
+				oo.setWaitingForResp(false)
+				return fmt.Errorf("wait-for-image-status-abort-msg-received")
+			}
+		default:
+			logger.Errorw(ctx, "waitForGetOnuImageStatus wrong msg type received", log.Fields{"msgType": message.Type, "device-id": oo.deviceID})
+			oo.setWaitingForResp(false)
+			return fmt.Errorf("wait-for-image-status-response-error")
+		}
+	}
+	logger.Errorw(ctx, "waitForGetOnuImageStatus processing error", log.Fields{"device-id": oo.deviceID})
+	oo.setWaitingForResp(false)
+	return fmt.Errorf("wait-for-image-status-processing-error")
+
+}
+
+func (oo *OnuImageStatus) processGetOnuImageStatusResp(ctx context.Context, msg cmn.OmciMessage, image *voltha.OnuImage) error {
+	if msg.OmciMsg.MessageType != omci.GetResponseType {
+		logger.Errorw(ctx, "processGetOnuImageStatusResp wrong response type received", log.Fields{"respType": msg.OmciMsg.MessageType, "device-id": oo.deviceID})
+		return fmt.Errorf("process-image-status-response-error")
+	}
+	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetResponse)
+	if msgLayer == nil {
+		logger.Errorw(ctx, "processGetOnuImageStatusResp omci Msg layer not found", log.Fields{"device-id": oo.deviceID})
+		return fmt.Errorf("process-image-status-response-error")
+	}
+	msgObj, msgOk := msgLayer.(*omci.GetResponse)
+	if !msgOk {
+		logger.Errorw(ctx, "processGetOnuImageStatusResp omci msgObj layer could not be found", log.Fields{"device-id": oo.deviceID})
+		return fmt.Errorf("process-image-status-response-error")
+	}
+	oo.mutexPLastTxMeInstance.RLock()
+	if oo.pLastTxMeInstance != nil {
+		if msgObj.EntityClass == oo.pLastTxMeInstance.GetClassID() &&
+			msgObj.EntityInstance == oo.pLastTxMeInstance.GetEntityID() {
+			oo.mutexPLastTxMeInstance.RUnlock()
+			if err := oo.processAttributesReceived(ctx, msgObj, image); err != nil {
+				logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oo.deviceID})
+				return err
+			}
+			return nil
+		}
+		oo.mutexPLastTxMeInstance.RUnlock()
+		logger.Errorw(ctx, "processGetOnuImageStatusResp wrong MeInstance received", log.Fields{"device-id": oo.deviceID})
+		return fmt.Errorf("process-image-status-response-error")
+	}
+	oo.mutexPLastTxMeInstance.RUnlock()
+	logger.Errorw(ctx, "processGetOnuImageStatusResp pLastTxMeInstance is nil", log.Fields{"device-id": oo.deviceID})
+	return fmt.Errorf("process-image-status-response-error")
+}
+
+func (oo *OnuImageStatus) processAttributesReceived(ctx context.Context, msgObj *omci.GetResponse, image *voltha.OnuImage) error {
+	meAttributes := msgObj.Attributes
+	logger.Debugw(ctx, "processAttributesReceived", log.Fields{"attributes": meAttributes, "device-id": oo.deviceID})
+
+	for k := range oo.requestedAttributes {
+
+		if msgObj.Result != me.Success && k != cImgProductCode && k != cImgImageHash {
+			logger.Errorw(ctx, "processAttributesReceived retrieval of mandatory attributes failed",
+				log.Fields{"device-id": oo.deviceID})
+			return fmt.Errorf("process-image-status-response-error")
+		}
+		switch k {
+
+		// mandatory attributes
+		case cImgIsCommitted:
+			if meAttributes[cImgIsCommitted].(uint8) == cmn.SwIsCommitted {
+				image.IsCommited = true
+			} else {
+				image.IsCommited = false
+			}
+		case cImgIsActive:
+			if meAttributes[cImgIsActive].(uint8) == cmn.SwIsActive {
+				image.IsActive = true
+			} else {
+				image.IsActive = false
+			}
+		case cImgIsValid:
+			if meAttributes[cImgIsValid].(uint8) == cmn.SwIsValid {
+				image.IsValid = true
+			} else {
+				image.IsValid = false
+			}
+		case cImgVersion:
+			image.Version = cmn.TrimStringFromMeOctet(meAttributes[cImgVersion])
+
+		// optional attributes
+		case cImgProductCode:
+			if msgObj.Result == me.Success {
+				image.ProductCode = cmn.TrimStringFromMeOctet(meAttributes[cImgProductCode])
+			} else {
+				sResult := msgObj.Result.String()
+				logger.Infow(ctx, "processAttributesReceived - ProductCode",
+					log.Fields{"result": sResult, "unsupported attribute mask": msgObj.UnsupportedAttributeMask, "device-id": oo.deviceID})
+				image.ProductCode = cResponse + sResult
+			}
+		case cImgImageHash:
+			if msgObj.Result == me.Success {
+				bytes, _ := me.InterfaceToOctets(meAttributes[cImgImageHash])
+				image.Hash = hex.EncodeToString(bytes)
+			} else {
+				sResult := msgObj.Result.String()
+				logger.Infow(ctx, "processAttributesReceived - ImageHash",
+					log.Fields{"result": sResult, "unsupported attribute mask": msgObj.UnsupportedAttributeMask, "device-id": oo.deviceID})
+				image.Hash = cResponse + sResult
+			}
+		}
+	}
+	return nil
+}
+
+func (oo *OnuImageStatus) updateOnuSwImageIndications(ctx context.Context, images *voltha.OnuImages) {
+
+	oo.pDevEntry.LockMutexOnuSwImageIndications()
+	onuSwImageIndications := oo.pDevEntry.GetOnuSwImageIndications()
+	validActiveImageFound := false
+	for i := cmn.FirstSwImageMeID; i <= cmn.SecondSwImageMeID; i++ {
+		if images.Items[i].IsActive && images.Items[i].IsValid {
+			onuSwImageIndications.ActiveEntityEntry.EntityID = uint16(i)
+			onuSwImageIndications.ActiveEntityEntry.Valid = images.Items[i].IsValid
+			onuSwImageIndications.ActiveEntityEntry.Version = images.Items[i].Version
+			if images.Items[i].IsCommited {
+				onuSwImageIndications.ActiveEntityEntry.IsCommitted = cmn.SwIsCommitted
+			} else {
+				onuSwImageIndications.ActiveEntityEntry.IsCommitted = cmn.SwIsUncommitted
+			}
+			validActiveImageFound = true
+			break
+		}
+	}
+	if !validActiveImageFound {
+		onuSwImageIndications.ActiveEntityEntry.Valid = false
+	}
+	validInactiveImageFound := false
+	for i := cmn.FirstSwImageMeID; i <= cmn.SecondSwImageMeID; i++ {
+		if !images.Items[i].IsActive && images.Items[i].IsValid {
+			onuSwImageIndications.InActiveEntityEntry.EntityID = uint16(i)
+			onuSwImageIndications.InActiveEntityEntry.Valid = images.Items[i].IsValid
+			onuSwImageIndications.InActiveEntityEntry.Version = images.Items[i].Version
+			if images.Items[i].IsCommited {
+				onuSwImageIndications.InActiveEntityEntry.IsCommitted = cmn.SwIsCommitted
+			} else {
+				onuSwImageIndications.InActiveEntityEntry.IsCommitted = cmn.SwIsUncommitted
+			}
+			validInactiveImageFound = true
+			break
+		}
+	}
+	if !validInactiveImageFound {
+		onuSwImageIndications.InActiveEntityEntry.Valid = false
+	}
+	oo.pDevEntry.SetOnuSwImageIndications(onuSwImageIndications)
+	oo.pDevEntry.UnlockMutexOnuSwImageIndications()
+}
+
+func (oo *OnuImageStatus) updateOnuSwImagePersistentData(ctx context.Context) {
+
+	activeImageVersion := oo.pDevEntry.GetActiveImageVersion(ctx)
+	oo.pDevEntry.LockMutexPersOnuConfig()
+	persActiveSwVersion := oo.pDevEntry.GetPersActiveSwVersion()
+	if persActiveSwVersion != activeImageVersion {
+		logger.Infow(ctx, "Active SW version has been changed at ONU - update persistent data",
+			log.Fields{"old version": persActiveSwVersion,
+				"new version": activeImageVersion, "device-id": oo.deviceID})
+		oo.pDevEntry.SetPersActiveSwVersion(activeImageVersion)
+		oo.pDevEntry.UnlockMutexPersOnuConfig()
+		if err := oo.pDeviceHandler.StorePersistentData(ctx); err != nil {
+			logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
+				log.Fields{"device-id": oo.deviceID, "err": err})
+		}
+		return
+	}
+	oo.pDevEntry.UnlockMutexPersOnuConfig()
+}
+
+func (oo *OnuImageStatus) setWaitingForResp(value bool) {
+	oo.mutexWaitingForResp.Lock()
+	oo.waitingForResp = value
+	oo.mutexWaitingForResp.Unlock()
+}
+
+func (oo *OnuImageStatus) isWaitingForResp() bool {
+	oo.mutexWaitingForResp.RLock()
+	value := oo.waitingForResp
+	oo.mutexWaitingForResp.RUnlock()
+	return value
+}
+
+//CancelProcessing ensures that interrupted processing is canceled while waiting for a response
+func (oo *OnuImageStatus) CancelProcessing(ctx context.Context) {
+	if oo.isWaitingForResp() {
+		abortMsg := cmn.Message{
+			Type: cmn.TestMsg,
+			Data: cmn.TestMessage{
+				TestMessageVal: cmn.AbortMessageProcessing,
+			},
+		}
+		oo.respChannel <- abortMsg
+	}
+}
