VOL-3052 Onu Software upgrade addendum: omci-lib-go update + download robustness

Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: I80f888f074e9a0ee82cd8f7b69404994e77885b1
diff --git a/VERSION b/VERSION
index 25b43e4..4f415ee 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.7-dev178
+1.2.7-dev179
diff --git a/go.mod b/go.mod
index 3eade05..db79a5a 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@
 	github.com/golang/protobuf v1.3.2
 	github.com/google/gopacket v1.1.17
 	github.com/looplab/fsm v0.1.0
-	github.com/opencord/omci-lib-go v0.15.4
+	github.com/opencord/omci-lib-go v0.16.2
 	github.com/opencord/voltha-lib-go/v4 v4.0.10
 	github.com/opencord/voltha-protos/v4 v4.0.13
 	github.com/stretchr/testify v1.6.1
diff --git a/go.sum b/go.sum
index 918cb85..d764d22 100644
--- a/go.sum
+++ b/go.sum
@@ -150,8 +150,8 @@
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
 github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/opencord/omci-lib-go v0.15.4 h1:g+IkuCZeS7Okvm7TxjobaLwX6UHo26hCvdyyqX9Bfi8=
-github.com/opencord/omci-lib-go v0.15.4/go.mod h1:6OIHB14Ch5qGgHzwSWlMACtk5KFoLzQ4LAhdcy4jwvo=
+github.com/opencord/omci-lib-go v0.16.2 h1:ywbaZLrLV+6VgyXV3I1LysdErt5HQutcin1CaaGRkA4=
+github.com/opencord/omci-lib-go v0.16.2/go.mod h1:6OIHB14Ch5qGgHzwSWlMACtk5KFoLzQ4LAhdcy4jwvo=
 github.com/opencord/voltha-lib-go/v4 v4.0.10 h1:mSi9e3TD+liit5NbV+AKEJ2dza3n+DpzdExJog2LtTo=
 github.com/opencord/voltha-lib-go/v4 v4.0.10/go.mod h1:K7lDkSkJ97EyfvX8fQtBmBvpj7n6MmwnAtD8Jz79HcQ=
 github.com/opencord/voltha-protos/v4 v4.0.12 h1:x8drb8inaUByjVLFbXSiQwRTU//dfde0MKIHyKb1JMw=
diff --git a/internal/pkg/onuadaptercore/adapter_download_manager.go b/internal/pkg/onuadaptercore/adapter_download_manager.go
index a49698f..e30d329 100644
--- a/internal/pkg/onuadaptercore/adapter_download_manager.go
+++ b/internal/pkg/onuadaptercore/adapter_download_manager.go
@@ -21,6 +21,7 @@
 	"bufio"
 	"context"
 	"errors"
+	"fmt"
 	"io"
 	"net/http"
 	"net/url"
@@ -115,7 +116,10 @@
 		}
 		//try to download from http
 		urlName := apImageDsc.Url + "/" + apImageDsc.Name
-		go dm.downloadFile(ctx, urlName, apImageDsc.LocalDir, 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
 	}
@@ -126,71 +130,105 @@
 }
 
 //downloadFile downloads the specified file from the given http location
-func (dm *adapterDownloadManager) downloadFile(ctx context.Context, aURLName string, aFilePath string, aFileName string) {
+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()
-	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)) //timeout to be discussed
-	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
+	//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.StatusCode != http.StatusOK {
+		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",
+				aURLName, errExist2, respExist.StatusCode)
+		}
 	}
 	defer func() {
-		deferredErr := resp.Body.Close()
+		deferredErr := respExist.Body.Close()
 		if deferredErr != nil {
-			logger.Errorw(ctx, "error at closing http response body", log.Fields{"url": urlBase.String(), "error": deferredErr})
+			logger.Errorw(ctx, "error at closing http head 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})
-		return
-	}
-	defer func() {
-		deferredErr := file.Close()
-		if deferredErr != nil {
-			logger.Errorw(ctx, "error at closing new file", log.Fields{"path_file": aLocalPathName, "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})
+			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 || respExist.StatusCode != http.StatusOK {
+			logger.Errorw(ctx, "could not http get from url", log.Fields{"url": urlBase.String(),
+				"error": err3, "status": respExist.StatusCode})
+			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})
+			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 err != nil {
+			logger.Errorw(ctx, "created file can't be accessed", log.Fields{"file": aLocalPathName, "stat-error": statsErr})
+		}
+		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
+			}
 		}
 	}()
-
-	// 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 err != nil {
-		logger.Errorw(ctx, "created file can't be accessed", log.Fields{"file": aLocalPathName, "stat-error": statsErr})
-	}
-	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
-		}
-	}
+	return nil
 }
 
 //writeFileToLFS writes the downloaded file to the local file system
diff --git a/internal/pkg/onuadaptercore/omci_onu_upgrade.go b/internal/pkg/onuadaptercore/omci_onu_upgrade.go
index c8c2c96..fd7df97 100644
--- a/internal/pkg/onuadaptercore/omci_onu_upgrade.go
+++ b/internal/pkg/onuadaptercore/omci_onu_upgrade.go
@@ -763,13 +763,12 @@
 				_ = oFsm.pAdaptFsm.pFsm.Event(upgradeEvAbort)
 				return
 			}
-			// TODO!!: not yet implemented by omci-lib:
-			/*if msgObj.Result != me.Success {
+			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})
 				// TODO!!!: error treatment?, perhaps in the end reset the FSM
 				return
-			}*/
+			}
 			if msgObj.EntityInstance == oFsm.inactiveImageMeID {
 				logger.Debugw(ctx, "OnuUpgradeFsm Expected SwImage CommitResponse received", log.Fields{"device-id": oFsm.deviceID})
 				//verifying committed image
diff --git a/vendor/github.com/opencord/omci-lib-go/VERSION b/vendor/github.com/opencord/omci-lib-go/VERSION
index 9f40a87..201a22c 100644
--- a/vendor/github.com/opencord/omci-lib-go/VERSION
+++ b/vendor/github.com/opencord/omci-lib-go/VERSION
@@ -1 +1 @@
-0.15.4
\ No newline at end of file
+0.16.2
diff --git a/vendor/github.com/opencord/omci-lib-go/mebase.go b/vendor/github.com/opencord/omci-lib-go/mebase.go
index 750233d..ec1b08c 100644
--- a/vendor/github.com/opencord/omci-lib-go/mebase.go
+++ b/vendor/github.com/opencord/omci-lib-go/mebase.go
@@ -65,11 +65,11 @@
 }
 
 // DecodeFromBytes decodes the given bytes into this layer
-func (msg *MeBasePacket) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
+func (msg *MeBasePacket) DecodeFromBytes(data []byte, p gopacket.PacketBuilder, contentSize int) error {
 	// Note: Base OMCI frame already checked for frame with at least 10 octets
 	msg.EntityClass = me.ClassID(binary.BigEndian.Uint16(data[0:]))
 	msg.EntityInstance = binary.BigEndian.Uint16(data[2:])
-	msg.BaseLayer = layers.BaseLayer{Contents: data[:4], Payload: data[4:]}
+	msg.BaseLayer = layers.BaseLayer{Contents: data[:contentSize], Payload: data[contentSize:]}
 	return nil
 }
 
diff --git a/vendor/github.com/opencord/omci-lib-go/meframe.go b/vendor/github.com/opencord/omci-lib-go/meframe.go
index 70edf4f..d53a669 100644
--- a/vendor/github.com/opencord/omci-lib-go/meframe.go
+++ b/vendor/github.com/opencord/omci-lib-go/meframe.go
@@ -286,7 +286,7 @@
 	WindowSize   uint8 // Window size - 1
 	ImageSize    uint32
 	CircuitPacks []uint16 // slot (upper 8 bits) and instance (lower 8 bits)
-	Results      []downloadResults
+	Results      []DownloadResults
 }
 
 var defaultSoftwareOptions = SoftwareOptions{
diff --git a/vendor/github.com/opencord/omci-lib-go/messagetypes.go b/vendor/github.com/opencord/omci-lib-go/messagetypes.go
index 6776b06..f0ff447 100644
--- a/vendor/github.com/opencord/omci-lib-go/messagetypes.go
+++ b/vendor/github.com/opencord/omci-lib-go/messagetypes.go
@@ -184,7 +184,7 @@
 // DecodeFromBytes decodes the given bytes of a Create Request into this layer
 func (omci *CreateRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
 	if err != nil {
 		return err
 	}
@@ -271,7 +271,7 @@
 // DecodeFromBytes decodes the given bytes of a Create Response into this layer
 func (omci *CreateResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
 	if err != nil {
 		return err
 	}
@@ -341,7 +341,7 @@
 // DecodeFromBytes decodes the given bytes of a Delete Request into this layer
 func (omci *DeleteRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
 	if err != nil {
 		return err
 	}
@@ -397,7 +397,7 @@
 // DecodeFromBytes decodes the given bytes of a Delete Response into this layer
 func (omci *DeleteResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -460,7 +460,7 @@
 // DecodeFromBytes decodes the given bytes of a Set Request into this layer
 func (omci *SetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -567,7 +567,7 @@
 // DecodeFromBytes decodes the given bytes of a Set Response into this layer
 func (omci *SetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
 	if err != nil {
 		return err
 	}
@@ -636,7 +636,7 @@
 // DecodeFromBytes decodes the given bytes of a Get Request into this layer
 func (omci *GetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -703,7 +703,7 @@
 // DecodeFromBytes decodes the given bytes of a Get Response into this layer
 func (omci *GetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
 	if err != nil {
 		return err
 	}
@@ -870,7 +870,7 @@
 // DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
 func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -948,7 +948,7 @@
 // DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
 func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -1021,7 +1021,7 @@
 // DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
 func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -1097,7 +1097,7 @@
 // DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
 func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4+28)
 	if err != nil {
 		return err
 	}
@@ -1173,7 +1173,7 @@
 // DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
 func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
 	if err != nil {
 		return err
 	}
@@ -1240,7 +1240,7 @@
 // DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
 func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -1313,7 +1313,7 @@
 // DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
 func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -1386,7 +1386,7 @@
 // DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
 func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+6)
 	if err != nil {
 		return err
 	}
@@ -1457,7 +1457,7 @@
 // DecodeFromBytes decodes the given bytes of a MIB Reset Request into this layer
 func (omci *MibResetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
 	if err != nil {
 		return err
 	}
@@ -1511,7 +1511,7 @@
 // DecodeFromBytes decodes the given bytes of a MIB Reset Response into this layer
 func (omci *MibResetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -1684,7 +1684,7 @@
 // DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
 func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+28)
 	if err != nil {
 		return err
 	}
@@ -1770,7 +1770,7 @@
 // DecodeFromBytes decodes the given bytes of an Attribute Value Change notification into this layer
 func (omci *AttributeValueChangeMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -1855,7 +1855,7 @@
 // DecodeFromBytes decodes the given bytes of a Test Request into this layer
 func (omci *TestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
 	if err != nil {
 		return err
 	}
@@ -1891,7 +1891,7 @@
 // DecodeFromBytes decodes the given bytes of a Test Response into this layer
 func (omci *TestResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -1931,7 +1931,7 @@
 
 // DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
 func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
 	if err != nil {
 		return err
 	}
@@ -2007,12 +2007,12 @@
 
 /////////////////////////////////////////////////////////////////////////////
 //
-type downloadResults struct {
+type DownloadResults struct {
 	ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
 	Result          me.Results
 }
 
-func (dr *downloadResults) String() string {
+func (dr *DownloadResults) String() string {
 	return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
 		dr.Result, dr.Result)
 }
@@ -2022,7 +2022,7 @@
 	Result            me.Results
 	WindowSize        byte // Window Size -1
 	NumberOfInstances byte
-	MeResults         []downloadResults
+	MeResults         []DownloadResults
 }
 
 func (omci *StartSoftwareDownloadResponse) String() string {
@@ -2033,7 +2033,7 @@
 // DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
 func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
 	if err != nil {
 		return err
 	}
@@ -2065,7 +2065,7 @@
 		return errors.New(msg)
 	}
 	if omci.NumberOfInstances > 0 {
-		omci.MeResults = make([]downloadResults, omci.NumberOfInstances)
+		omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
 
 		for index := 0; index < int(omci.NumberOfInstances); index++ {
 			omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[7+(index*3):])
@@ -2155,7 +2155,7 @@
 // DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
 func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -2228,7 +2228,7 @@
 // DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
 func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -2313,7 +2313,7 @@
 // DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
 func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
 	if err != nil {
 		return err
 	}
@@ -2395,7 +2395,7 @@
 	MeBasePacket      // Note: EntityInstance for software download is two specific values
 	Result            me.Results
 	NumberOfInstances byte
-	MeResults         []downloadResults
+	MeResults         []DownloadResults
 }
 
 func (omci *EndSoftwareDownloadResponse) String() string {
@@ -2406,7 +2406,7 @@
 // DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
 func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -2437,7 +2437,7 @@
 		return errors.New(msg)
 	}
 	if omci.NumberOfInstances > 0 {
-		omci.MeResults = make([]downloadResults, omci.NumberOfInstances)
+		omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
 
 		for index := 0; index < int(omci.NumberOfInstances); index++ {
 			omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
@@ -2525,7 +2525,7 @@
 // DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
 func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -2604,7 +2604,7 @@
 // DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
 func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -2682,7 +2682,7 @@
 // DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
 func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
 	if err != nil {
 		return err
 	}
@@ -2735,6 +2735,7 @@
 //
 type CommitSoftwareResponse struct {
 	MeBasePacket
+	Result me.Results
 }
 
 func (omci *CommitSoftwareResponse) String() string {
@@ -2744,7 +2745,7 @@
 // DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
 func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -2753,7 +2754,7 @@
 	if omciErr.StatusCode() != me.Success {
 		return omciErr.GetError()
 	}
-	// ME needs to support End Software Download
+	// ME needs to support Commit Software
 	if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
 		return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
 	}
@@ -2761,6 +2762,12 @@
 	if omci.EntityClass != me.SoftwareImageClassID {
 		return me.NewProcessingError("invalid Entity Class for Commit Software response")
 	}
+	omci.Result = me.Results(data[4])
+	if omci.Result > me.Results(6) {
+		msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
+			omci.Result)
+		return errors.New(msg)
+	}
 	return nil
 }
 
@@ -2782,7 +2789,7 @@
 	if omciErr.StatusCode() != me.Success {
 		return omciErr.GetError()
 	}
-	// ME needs to support End Software Download
+	// ME needs to support Commit Software
 	if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
 		return me.NewProcessingError("managed entity does not support Commit Message-Type")
 	}
@@ -2790,6 +2797,16 @@
 	if omci.EntityClass != me.SoftwareImageClassID {
 		return me.NewProcessingError("invalid Entity Class for Commit Software response")
 	}
+	bytes, err := b.AppendBytes(1)
+	if err != nil {
+		return err
+	}
+	bytes[0] = byte(omci.Result)
+	if omci.Result > me.Results(6) {
+		msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
+			omci.Result)
+		return errors.New(msg)
+	}
 	return nil
 }
 
@@ -2813,7 +2830,7 @@
 // DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
 func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
 	if err != nil {
 		return err
 	}
@@ -2893,7 +2910,7 @@
 // DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
 func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -2981,7 +2998,7 @@
 // DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
 func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -3052,7 +3069,7 @@
 // DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
 func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
 	if err != nil {
 		return err
 	}
@@ -3123,7 +3140,7 @@
 // DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
 func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
 	if err != nil {
 		return err
 	}
@@ -3194,7 +3211,7 @@
 // DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
 func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
 	if err != nil {
 		return err
 	}
@@ -3312,7 +3329,7 @@
 // DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
 func (omci *TestResultMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
 	if err != nil {
 		return err
 	}
@@ -3350,7 +3367,7 @@
 // DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
 func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
 	if err != nil {
 		return err
 	}
@@ -3416,7 +3433,7 @@
 // DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
 func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
 	if err != nil {
 		return err
 	}
@@ -3503,7 +3520,7 @@
 // DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
 func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+2)
 	if err != nil {
 		return err
 	}
@@ -3540,7 +3557,7 @@
 // DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
 func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
 	// Common ClassID/EntityID decode in msgBase
-	err := omci.MeBasePacket.DecodeFromBytes(data, p)
+	err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+1)
 	if err != nil {
 		return err
 	}
diff --git a/vendor/github.com/opencord/omci-lib-go/omci.go b/vendor/github.com/opencord/omci-lib-go/omci.go
index 3904352..e347b48 100644
--- a/vendor/github.com/opencord/omci-lib-go/omci.go
+++ b/vendor/github.com/opencord/omci-lib-go/omci.go
@@ -113,8 +113,8 @@
 	MessageType      MessageType
 	DeviceIdentifier DeviceIdent
 	ResponseExpected bool // Significant for Download Section Request only
-	Payload          []byte
-	padding          []byte
+	Payload          []byte		// TODO: Deprecated.  Use layers.BaseLayer.Payload
+	padding          []byte		// TODO: Deprecated.  Never Used
 	Length           uint16
 	MIC              uint32
 }
@@ -137,7 +137,7 @@
 
 // LayerContents returns the OMCI specific layer information
 func (omci *OMCI) LayerContents() []byte {
-	b := make([]byte, 8)
+	b := make([]byte, 4)
 	binary.BigEndian.PutUint16(b, omci.TransactionID)
 	b[2] = byte(omci.MessageType)
 	b[3] = byte(omci.DeviceIdentifier)
@@ -252,7 +252,7 @@
 			//return errors.New(msg)
 		}
 	}
-	omci.BaseLayer = layers.BaseLayer{data[:4], data[4:]}
+	omci.BaseLayer = layers.BaseLayer{data[:4], data[4:omci.Length]}
 	p.AddLayer(omci)
 	nextLayer, err := MsgTypeToNextLayer(omci.MessageType)
 	if err != nil {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index a385aa7..5d9320f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -55,7 +55,7 @@
 github.com/jcmturner/gofork/x/crypto/pbkdf2
 # github.com/looplab/fsm v0.1.0
 github.com/looplab/fsm
-# github.com/opencord/omci-lib-go v0.15.4
+# github.com/opencord/omci-lib-go v0.16.2
 github.com/opencord/omci-lib-go
 github.com/opencord/omci-lib-go/generated
 # github.com/opencord/voltha-lib-go/v4 v4.0.10