Converting Software Image Hash to hex string
Returning image version based on the first 14 bytes of the image file. D
Change-Id: I5ea94be5e841cd1a845e7d523cf0e3666983d4aa
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 84706fd..af135de 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -127,6 +127,9 @@
ImageSoftwareReceivedSections int
ActiveImageEntityId uint16
CommittedImageEntityId uint16
+ StandbyImageVersion string
+ ActiveImageVersion string
+ CommittedImageVersion string
OmciResponseRate uint8
OmciMsgCounter uint8
@@ -163,10 +166,14 @@
MibDataSync: 0,
ImageSoftwareExpectedSections: 0, // populated during OMCI StartSoftwareDownloadRequest
ImageSoftwareReceivedSections: 0,
- ActiveImageEntityId: 0, // when we start the SoftwareImage with ID 0 is active and committed
- CommittedImageEntityId: 0,
- OmciResponseRate: olt.OmciResponseRate,
- OmciMsgCounter: 0,
+ //TODO this needs reworking, it's always 0 or 1, possibly base all on the version
+ ActiveImageEntityId: 0, // when we start the SoftwareImage with ID 0 is active and committed
+ CommittedImageEntityId: 0,
+ StandbyImageVersion: "BBSM_IMG_00000",
+ ActiveImageVersion: "BBSM_IMG_00001",
+ CommittedImageVersion: "BBSM_IMG_00001",
+ OmciResponseRate: olt.OmciResponseRate,
+ OmciMsgCounter: 0,
}
o.SerialNumber = NewSN(olt.ID, pon.ID, id)
// NOTE this state machine is used to track the operational
@@ -782,7 +789,8 @@
responsePkt, _ = omcilib.CreateMibUploadNextResponse(msg.OmciPkt, msg.OmciMsg, o.MibDataSync, o.MibDb)
case omci.GetRequestType:
onuDown := o.OperState.Current() == "down"
- responsePkt, _ = omcilib.CreateGetResponse(msg.OmciPkt, msg.OmciMsg, o.SerialNumber, o.MibDataSync, o.ActiveImageEntityId, o.CommittedImageEntityId, onuDown)
+ responsePkt, _ = omcilib.CreateGetResponse(msg.OmciPkt, msg.OmciMsg, o.SerialNumber, o.MibDataSync, o.ActiveImageEntityId,
+ o.CommittedImageEntityId, o.StandbyImageVersion, o.ActiveImageVersion, o.CommittedImageVersion, onuDown)
case omci.SetRequestType:
success := true
msgObj, _ := omcilib.ParseSetRequest(msg.OmciPkt)
@@ -1011,6 +1019,10 @@
"SectionNumber": msgObj.SectionNumber,
"SectionData": msgObj.SectionData,
}).Trace("received-download-section-request")
+ //Extracting the first 14 bytes to use as a version for this image.
+ if o.ImageSoftwareReceivedSections == 0 {
+ o.StandbyImageVersion = string(msgObj.SectionData[0:14])
+ }
o.ImageSoftwareReceivedSections++
if o.InternalState.Current() != OnuStateImageDownloadInProgress {
if err := o.InternalState.Event(OnuTxProgressImageDownload); err != nil {
@@ -1101,6 +1113,9 @@
}
if msgObj, err := omcilib.ParseActivateSoftwareRequest(msg.OmciPkt); err == nil {
o.ActiveImageEntityId = msgObj.EntityInstance
+ previousActiveImage := o.ActiveImageVersion
+ o.ActiveImageVersion = o.StandbyImageVersion
+ o.StandbyImageVersion = previousActiveImage
} else {
onuLogger.Errorf("something-went-wrong-while-activating: %s", err)
}
@@ -1134,7 +1149,11 @@
// TODO validate that the image to commit is:
// - active
// - not already committed
+ o.ActiveImageEntityId = msgObj.EntityInstance
o.CommittedImageEntityId = msgObj.EntityInstance
+ //committed becomes standby
+ o.StandbyImageVersion = o.CommittedImageVersion
+ o.CommittedImageVersion = o.ActiveImageVersion
} else {
onuLogger.Errorf("something-went-wrong-while-committing: %s", err)
}
diff --git a/internal/common/omci/get.go b/internal/common/omci/get.go
index 73e53ac..e50c47a 100644
--- a/internal/common/omci/get.go
+++ b/internal/common/omci/get.go
@@ -45,7 +45,9 @@
return msgObj, nil
}
-func CreateGetResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI, onuSn *openolt.SerialNumber, mds uint8, activeImageEntityId uint16, committedImageEntityId uint16, onuDown bool) ([]byte, error) {
+func CreateGetResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI, onuSn *openolt.SerialNumber, mds uint8,
+ activeImageEntityId uint16, committedImageEntityId uint16, standbyImageVersion string, activeImageVersion string,
+ committedImageVersion string, onuDown bool) ([]byte, error) {
msgObj, err := ParseGetRequest(omciPkt)
@@ -66,7 +68,8 @@
case me.OnuGClassID:
response = createOnugResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuSn)
case me.SoftwareImageClassID:
- response = createSoftwareImageResponse(msgObj.AttributeMask, msgObj.EntityInstance, activeImageEntityId, committedImageEntityId)
+ response = createSoftwareImageResponse(msgObj.AttributeMask, msgObj.EntityInstance,
+ activeImageEntityId, committedImageEntityId, standbyImageVersion, activeImageVersion, committedImageVersion)
case me.IpHostConfigDataClassID:
response = createIpHostResponse(msgObj.AttributeMask, msgObj.EntityInstance)
case me.UniGClassID:
@@ -200,20 +203,35 @@
//}
}
-func createSoftwareImageResponse(attributeMask uint16, entityInstance uint16, activeImageEntityId uint16, committedImageEntityId uint16) *omci.GetResponse {
+func createSoftwareImageResponse(attributeMask uint16, entityInstance uint16, activeImageEntityId uint16,
+ committedImageEntityId uint16, standbyImageVersion string, activeImageVersion string, committedImageVersion string) *omci.GetResponse {
omciLogger.WithFields(log.Fields{
"EntityInstance": entityInstance,
+ "AttributeMask": attributeMask,
}).Trace("received-get-software-image-request")
// Only one image can be active and committed
committed := 0
active := 0
+ version := standbyImageVersion
if entityInstance == activeImageEntityId {
active = 1
+ version = activeImageVersion
}
if entityInstance == committedImageEntityId {
committed = 1
+ version = committedImageVersion
+ }
+
+ imageHash, err := hex.DecodeString(hex.EncodeToString([]byte(version)))
+ if err != nil {
+ omciLogger.WithFields(log.Fields{
+ "entityId": entityInstance,
+ "active": active,
+ "committed": committed,
+ "err": err,
+ }).Error("cannot-generate-image-hash")
}
// NOTE that we need send the response for the correct ME Instance or the adapter won't process it
@@ -224,12 +242,12 @@
},
Attributes: me.AttributeValueMap{
"ManagedEntityId": 0,
- "Version": ToOctets("00000000000001", 14),
+ "Version": ToOctets(version, 14),
"IsCommitted": committed,
"IsActive": active,
"IsValid": 1,
- "ProductCode": ToOctets("product-code", 25),
- "ImageHash": ToOctets("broadband-sim", 16),
+ "ProductCode": ToOctets("BBSIM-ONU", 25),
+ "ImageHash": imageHash,
},
Result: me.Success,
AttributeMask: attributeMask,
diff --git a/internal/common/omci/get_test.go b/internal/common/omci/get_test.go
index 0d9663f..f9cdac4 100644
--- a/internal/common/omci/get_test.go
+++ b/internal/common/omci/get_test.go
@@ -24,6 +24,7 @@
me "github.com/opencord/omci-lib-go/generated"
"github.com/opencord/voltha-protos/v4/go/openolt"
"gotest.tools/assert"
+ "reflect"
"testing"
)
@@ -108,6 +109,26 @@
getArgs{createEthernetPerformanceMonitoringHistoryDataResponse(32768, 10), 2},
getWant{2, map[string]interface{}{"ManagedEntityId": uint16(10)}},
},
+ {"getSoftwareImageResponse",
+ getArgs{createSoftwareImageResponse(61440, 0, 1, 1, "BBSM_IMG_00000", "BBSM_IMG_00001", "BBSM_IMG_00001"), 2},
+ getWant{2, map[string]interface{}{"IsCommitted": uint8(0), "IsActive": uint8(0)}},
+ },
+ {"getSoftwareImageResponseActiveCommitted",
+ getArgs{createSoftwareImageResponse(61440, 1, 1, 1, "BBSM_IMG_00000", "BBSM_IMG_00001", "BBSM_IMG_00001"), 2},
+ getWant{2, map[string]interface{}{"IsCommitted": uint8(1), "IsActive": uint8(1)}},
+ },
+ {"getSoftwareImageResponseVersion",
+ getArgs{createSoftwareImageResponse(61440, 1, 1, 1, "BBSM_IMG_00000", "BBSM_IMG_00001", "BBSM_IMG_00001"), 2},
+ getWant{2, map[string]interface{}{"Version": ToOctets("BBSM_IMG_00001", 14)}},
+ },
+ {"getSoftwareImageResponseProductCode",
+ getArgs{createSoftwareImageResponse(2048, 1, 1, 1, "BBSM_IMG_00000", "BBSM_IMG_00001", "BBSM_IMG_00001"), 2},
+ getWant{2, map[string]interface{}{"ProductCode": ToOctets("BBSIM-ONU", 25)}},
+ },
+ {"getSoftwareImageResponseActiveImageHash",
+ getArgs{createSoftwareImageResponse(1024, 1, 1, 1, "BBSM_IMG_00000", "BBSM_IMG_00001", "BBSM_IMG_00001"), 2},
+ getWant{2, map[string]interface{}{"ImageHash": ToOctets("BBSM_IMG_00001", 25)}},
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -135,7 +156,18 @@
for k, v := range tt.want.attributes {
attr := getResponseLayer.Attributes[k]
- assert.Equal(t, attr, v)
+ attrValue := reflect.ValueOf(attr)
+ if attrValue.Kind() == reflect.Slice {
+ // it the attribute is a list, iterate and compare single values
+ expectedValue := reflect.ValueOf(v)
+ for i := 0; i < attrValue.Len(); i++ {
+ assert.Equal(t, attrValue.Index(i).Interface(), expectedValue.Index(i).Interface(),
+ fmt.Sprintf("Attribute %s does not match, expected: %s, received %s", k, v, attr))
+ }
+ } else {
+ // if it's not a list just compare
+ assert.Equal(t, attr, v)
+ }
}
})
}