[VOL-3880] Correctly reporting software image status in OMCI Get
[VOL-3900] OMCI ONU Software Image Download
Change-Id: I8d91be832f3a89404d0af0dd98e6b53359e6a738
diff --git a/internal/common/omci/image.go b/internal/common/omci/image.go
new file mode 100644
index 0000000..8480ecb
--- /dev/null
+++ b/internal/common/omci/image.go
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2018-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 omci
+
+import (
+ "encoding/hex"
+ "errors"
+ "github.com/google/gopacket"
+ "github.com/opencord/omci-lib-go"
+ me "github.com/opencord/omci-lib-go/generated"
+ log "github.com/sirupsen/logrus"
+ "math"
+ "strconv"
+)
+
+func ParseStartSoftwareDownloadRequest(omciPkt gopacket.Packet) (*omci.StartSoftwareDownloadRequest, error) {
+ msgLayer := omciPkt.Layer(omci.LayerTypeStartSoftwareDownloadRequest)
+ if msgLayer == nil {
+ err := "omci Msg layer could not be detected for LayerTypeStartSoftwareDownloadRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ msgObj, msgOk := msgLayer.(*omci.StartSoftwareDownloadRequest)
+ if !msgOk {
+ err := "omci Msg layer could not be assigned for LayerTypeStartSoftwareDownloadRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ return msgObj, nil
+}
+
+func ParseDownloadSectionRequest(omciPkt gopacket.Packet) (*omci.DownloadSectionRequest, error) {
+ msgLayer := omciPkt.Layer(omci.LayerTypeDownloadSectionRequest)
+ if msgLayer == nil {
+ err := "omci Msg layer could not be detected for LayerTypeDownloadSectionRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ msgObj, msgOk := msgLayer.(*omci.DownloadSectionRequest)
+ if !msgOk {
+ err := "omci Msg layer could not be assigned for LayerTypeDownloadSectionRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ return msgObj, nil
+}
+
+func ParseEndSoftwareDownloadRequest(omciPkt gopacket.Packet) (*omci.EndSoftwareDownloadRequest, error) {
+ msgLayer := omciPkt.Layer(omci.LayerTypeEndSoftwareDownloadRequest)
+ if msgLayer == nil {
+ err := "omci Msg layer could not be detected for LayerTypeEndSoftwareDownloadRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ msgObj, msgOk := msgLayer.(*omci.EndSoftwareDownloadRequest)
+ if !msgOk {
+ err := "omci Msg layer could not be assigned for LayerTypeEndSoftwareDownloadRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ return msgObj, nil
+}
+
+func ParseActivateSoftwareRequest(omciPkt gopacket.Packet) (*omci.ActivateSoftwareRequest, error) {
+ msgLayer := omciPkt.Layer(omci.LayerTypeActivateSoftwareRequest)
+ if msgLayer == nil {
+ err := "omci Msg layer could not be detected for LayerTypeActivateSoftwareRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ msgObj, msgOk := msgLayer.(*omci.ActivateSoftwareRequest)
+ if !msgOk {
+ err := "omci Msg layer could not be assigned for LayerTypeActivateSoftwareRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ return msgObj, nil
+}
+
+func ParseCommitSoftwareRequest(omciPkt gopacket.Packet) (*omci.CommitSoftwareRequest, error) {
+ msgLayer := omciPkt.Layer(omci.LayerTypeCommitSoftwareRequest)
+ if msgLayer == nil {
+ err := "omci Msg layer could not be detected for LayerTypeCommitSoftwareRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ msgObj, msgOk := msgLayer.(*omci.CommitSoftwareRequest)
+ if !msgOk {
+ err := "omci Msg layer could not be assigned for LayerTypeCommitSoftwareRequest"
+ omciLogger.Error(err)
+ return nil, errors.New(err)
+ }
+ return msgObj, nil
+}
+
+func CreateStartSoftwareDownloadResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI) ([]byte, error) {
+ responeCode := me.Success
+ msgObj, err := ParseStartSoftwareDownloadRequest(omciPkt)
+ if err != nil {
+ responeCode = me.ProcessingError
+ }
+
+ omciLogger.WithFields(log.Fields{
+ "OmciMsgType": omciMsg.MessageType,
+ "TransCorrId": omciMsg.TransactionID,
+ "EntityInstance": msgObj.EntityInstance,
+ "WindowSize": msgObj.WindowSize,
+ "ImageSize": msgObj.ImageSize,
+ "NumberOfCircuitPacks": msgObj.NumberOfCircuitPacks,
+ "CircuitPacks": msgObj.CircuitPacks,
+ }).Debug("received-start-software-download-request")
+
+ response := &omci.StartSoftwareDownloadResponse{
+ MeBasePacket: omci.MeBasePacket{
+ EntityClass: msgObj.EntityClass,
+ EntityInstance: msgObj.EntityInstance,
+ },
+ WindowSize: msgObj.WindowSize,
+ Result: responeCode,
+ NumberOfInstances: 0, // NOTE this can't be bigger than 0 this we can populate downloadResults
+ MeResults: []omci.DownloadResults{}, // FIXME downloadResults is not exported
+ }
+
+ pkt, err := Serialize(omci.StartSoftwareDownloadResponseType, response, omciMsg.TransactionID)
+ if err != nil {
+ omciLogger.WithFields(log.Fields{
+ "Err": err,
+ }).Error("cannot-Serialize-CreateResponse")
+ return nil, err
+ }
+
+ log.WithFields(log.Fields{
+ "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+ "pkt": hex.EncodeToString(pkt),
+ }).Trace("omci-start-software-download-response")
+
+ return pkt, nil
+}
+
+func CreateDownloadSectionResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI) ([]byte, error) {
+
+ msgObj, err := ParseDownloadSectionRequest(omciPkt)
+
+ if err != nil {
+ return nil, err
+ }
+
+ omciLogger.WithFields(log.Fields{
+ "OmciMsgType": omciMsg.MessageType,
+ "TransCorrId": omciMsg.TransactionID,
+ "EntityInstance": msgObj.EntityInstance,
+ "SectionNumber": msgObj.SectionNumber,
+ }).Debug("received-download-section-request")
+
+ response := &omci.DownloadSectionResponse{
+ MeBasePacket: omci.MeBasePacket{
+ EntityClass: msgObj.EntityClass,
+ EntityInstance: msgObj.EntityInstance,
+ },
+ Result: me.Success,
+ SectionNumber: msgObj.SectionNumber,
+ }
+
+ pkt, err := Serialize(omci.DownloadSectionResponseType, response, omciMsg.TransactionID)
+ if err != nil {
+ return nil, err
+ }
+
+ log.WithFields(log.Fields{
+ "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+ "pkt": hex.EncodeToString(pkt),
+ }).Trace("omci-download-section-with-response-response")
+
+ return pkt, nil
+}
+
+func CreateEndSoftwareDownloadResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI, status me.Results) ([]byte, error) {
+
+ msgObj, err := ParseEndSoftwareDownloadRequest(omciPkt)
+
+ if err != nil {
+ return nil, err
+ }
+
+ omciLogger.WithFields(log.Fields{
+ "OmciMsgType": omciMsg.MessageType,
+ "TransCorrId": omciMsg.TransactionID,
+ "EntityInstance": msgObj.EntityInstance,
+ "Crc32": msgObj.CRC32,
+ "ImageSize": msgObj.ImageSize,
+ "NumberOfInstances": msgObj.NumberOfInstances,
+ "ImageInstances": msgObj.ImageInstances,
+ }).Debug("received-end-software-download-request")
+
+ response := &omci.EndSoftwareDownloadResponse{
+ MeBasePacket: omci.MeBasePacket{
+ EntityClass: msgObj.EntityClass,
+ EntityInstance: msgObj.EntityInstance,
+ },
+ Result: status,
+ NumberOfInstances: 0, // NOTE this can't be bigger than 0 this we can populate downloadResults
+ //MeResults: []omci.downloadResults{}, // FIXME downloadResults is not exported
+ }
+
+ pkt, err := Serialize(omci.EndSoftwareDownloadResponseType, response, omciMsg.TransactionID)
+ if err != nil {
+ return nil, err
+ }
+
+ log.WithFields(log.Fields{
+ "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+ "pkt": hex.EncodeToString(pkt),
+ }).Trace("omci-end-software-download-response")
+
+ return pkt, nil
+}
+
+func CreateActivateSoftwareResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI) ([]byte, error) {
+
+ msgObj, err := ParseActivateSoftwareRequest(omciPkt)
+
+ if err != nil {
+ return nil, err
+ }
+
+ omciLogger.WithFields(log.Fields{
+ "OmciMsgType": omciMsg.MessageType,
+ "TransCorrId": omciMsg.TransactionID,
+ "EntityInstance": msgObj.EntityInstance,
+ "ActivateFlags": msgObj.ActivateFlags,
+ }).Debug("received-activate-software-request")
+
+ response := &omci.ActivateSoftwareResponse{
+ MeBasePacket: omci.MeBasePacket{
+ EntityClass: msgObj.EntityClass,
+ EntityInstance: msgObj.EntityInstance,
+ },
+ Result: me.Success,
+ }
+
+ pkt, err := Serialize(omci.ActivateSoftwareResponseType, response, omciMsg.TransactionID)
+ if err != nil {
+ return nil, err
+ }
+
+ log.WithFields(log.Fields{
+ "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+ "pkt": hex.EncodeToString(pkt),
+ }).Trace("omci-activate-software-response")
+
+ return pkt, nil
+}
+
+func CreateCommitSoftwareResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI) ([]byte, error) {
+
+ msgObj, err := ParseCommitSoftwareRequest(omciPkt)
+
+ if err != nil {
+ return nil, err
+ }
+
+ omciLogger.WithFields(log.Fields{
+ "OmciMsgType": omciMsg.MessageType,
+ "TransCorrId": omciMsg.TransactionID,
+ "EntityInstance": msgObj.EntityInstance,
+ }).Debug("received-commit-software-request")
+
+ response := &omci.CommitSoftwareResponse{
+ MeBasePacket: omci.MeBasePacket{
+ EntityClass: msgObj.EntityClass,
+ EntityInstance: msgObj.EntityInstance,
+ },
+ }
+
+ pkt, err := Serialize(omci.CommitSoftwareResponseType, response, omciMsg.TransactionID)
+ if err != nil {
+ return nil, err
+ }
+
+ log.WithFields(log.Fields{
+ "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+ "pkt": hex.EncodeToString(pkt),
+ }).Trace("omci-commit-software-response")
+
+ return pkt, nil
+}
+
+func ComputeDownloadSectionsCount(pkt gopacket.Packet) int {
+ msgObj, err := ParseStartSoftwareDownloadRequest(pkt)
+ if err != nil {
+ omciLogger.Error("cannot-parse-start-software-download-request")
+ }
+
+ return int(math.Ceil(float64(msgObj.ImageSize) / float64(msgObj.WindowSize)))
+}