WIP [VOL-4702] openonuAdapterGo: OMCI extended message set - support MIB upload

Change-Id: I85ac239970b2753591fb84bd7a1fa948423d9760
diff --git a/internal/pkg/common/interfaces.go b/internal/pkg/common/interfaces.go
index 25c8da7..e1cc2ec 100755
--- a/internal/pkg/common/interfaces.go
+++ b/internal/pkg/common/interfaces.go
@@ -132,6 +132,7 @@
 	GetPersSerialNumber() string
 	GetPersVendorID() string
 	GetPersEquipmentID() string
+	GetPersIsExtOmciSupported() bool
 
 	GetMibUploadFsmCommChan() chan Message
 	GetMibDownloadFsmCommChan() chan Message
diff --git a/internal/pkg/common/omci_cc.go b/internal/pkg/common/omci_cc.go
index ffe44ea..71c8116 100755
--- a/internal/pkg/common/omci_cc.go
+++ b/internal/pkg/common/omci_cc.go
@@ -880,13 +880,28 @@
 // SendMibUpload sends MibUploadRequest
 func (oo *OmciCC) SendMibUpload(ctx context.Context, timeout int, highPrio bool) error {
 	logger.Debugw(ctx, "send MibUpload-msg to:", log.Fields{"device-id": oo.deviceID})
+
+	tid := oo.GetNextTid(highPrio)
+	isExtended := oo.pOnuDeviceEntry.GetPersIsExtOmciSupported()
+
+	omciLayer := &omci.OMCI{
+		TransactionID: tid,
+		MessageType:   omci.MibUploadRequestType,
+	}
+	if isExtended {
+		omciLayer.DeviceIdentifier = omci.ExtendedIdent
+	}
 	request := &omci.MibUploadRequest{
 		MeBasePacket: omci.MeBasePacket{
 			EntityClass: me.OnuDataClassID,
+			Extended:    isExtended,
 		},
 	}
-	tid := oo.GetNextTid(highPrio)
-	pkt, err := Serialize(ctx, omci.MibUploadRequestType, request, tid)
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
+
+	buffer := gopacket.NewSerializeBuffer()
+	err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
 	if err != nil {
 		logger.Errorw(ctx, "Cannot serialize MibUploadRequest", log.Fields{
 			"Err": err, "device-id": oo.deviceID})
@@ -899,20 +914,35 @@
 		CbKey:   tid,
 		CbEntry: CallbackPairEntry{oo.pOnuDeviceEntry.GetMibUploadFsmCommChan(), oo.receiveOmciResponse, true},
 	}
-	return oo.Send(ctx, pkt, timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
+	return oo.Send(ctx, buffer.Bytes(), timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
 }
 
 // SendMibUploadNext sends MibUploadNextRequest
 func (oo *OmciCC) SendMibUploadNext(ctx context.Context, timeout int, highPrio bool) error {
 	logger.Debugw(ctx, "send MibUploadNext-msg to:", log.Fields{"device-id": oo.deviceID, "UploadSequNo": oo.UploadSequNo})
+
+	tid := oo.GetNextTid(highPrio)
+	isExtended := oo.pOnuDeviceEntry.GetPersIsExtOmciSupported()
+
+	omciLayer := &omci.OMCI{
+		TransactionID: tid,
+		MessageType:   omci.MibUploadNextRequestType,
+	}
+	if isExtended {
+		omciLayer.DeviceIdentifier = omci.ExtendedIdent
+	}
 	request := &omci.MibUploadNextRequest{
 		MeBasePacket: omci.MeBasePacket{
 			EntityClass: me.OnuDataClassID,
+			Extended:    isExtended,
 		},
 		CommandSequenceNumber: oo.UploadSequNo,
 	}
-	tid := oo.GetNextTid(highPrio)
-	pkt, err := Serialize(ctx, omci.MibUploadNextRequestType, request, tid)
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
+
+	buffer := gopacket.NewSerializeBuffer()
+	err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
 	if err != nil {
 		logger.Errorw(ctx, "Cannot serialize MibUploadNextRequest", log.Fields{
 			"Err": err, "device-id": oo.deviceID})
@@ -927,7 +957,7 @@
 		// compare also software upgrade download section handling
 		CbEntry: CallbackPairEntry{oo.pOnuDeviceEntry.GetMibUploadFsmCommChan(), oo.receiveOmciResponse, true},
 	}
-	return oo.Send(ctx, pkt, timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
+	return oo.Send(ctx, buffer.Bytes(), timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
 }
 
 // SendGetAllAlarm gets all alarm ME instances
diff --git a/internal/pkg/mib/mib_sync.go b/internal/pkg/mib/mib_sync.go
index b5d1ff9..60eb72f 100755
--- a/internal/pkg/mib/mib_sync.go
+++ b/internal/pkg/mib/mib_sync.go
@@ -634,7 +634,6 @@
 
 func (oo *OnuDeviceEntry) handleOmciMibUploadNextResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
 	msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeMibUploadNextResponse)
-
 	if msgLayer != nil {
 		msgObj, msgOk := msgLayer.(*omci.MibUploadNextResponse)
 		if !msgOk {
@@ -676,6 +675,38 @@
 			}
 			oo.pOnuDB.PutMe(ctx, meClassID, meEntityID, msgObj.ReportedME.GetAttributeValueMap())
 		}
+		if msg.OmciMsg.DeviceIdentifier == omci.ExtendedIdent {
+			for _, additionalME := range msgObj.AdditionalMEs {
+				meName := additionalME.GetName()
+				meClassID := additionalME.GetClassID()
+				meEntityID := additionalME.GetEntityID()
+				attributes := additionalME.GetAttributeValueMap()
+
+				if meName == devdb.CUnknownItuG988ManagedEntity || meName == devdb.CUnknownVendorSpecificManagedEntity {
+					attribMask := additionalME.GetAttributeMask()
+					logger.Debugw(ctx, "MibUploadNextResponse AdditionalData contains unknown ME", log.Fields{"device-id": oo.deviceID,
+						"Me-Name": devdb.UnknownMeOrAttribName(meName), "Me-ClassId": meClassID, "Me-InstId": meEntityID,
+						"unknown mask": attribMask})
+
+					attribValues := make([]byte, 0)
+					for key, value := range attributes {
+						if key != cmn.CGenericManagedEntityIDName {
+							data, err := me.InterfaceToOctets(value)
+							if err != nil {
+								logger.Infow(ctx, "MibUploadNextResponse unknown ME AdditionalData attrib - could not decode", log.Fields{"device-id": oo.deviceID, "key": key})
+							} else {
+								attribValues = append(attribValues[:], data[:]...)
+								logger.Debugw(ctx, "MibUploadNextResponse unknown ME AdditionalData attrib", log.Fields{"device-id": oo.deviceID, "attribValues": attribValues, "data": data, "key": key})
+							}
+						}
+					}
+					oo.pOnuDB.PutUnknownMeOrAttrib(ctx, devdb.UnknownMeOrAttribName(meName), meClassID, meEntityID, attribMask, attribValues)
+				} else {
+					logger.Debugw(ctx, "MibUploadNextResponse AdditionalData for:", log.Fields{"device-id": oo.deviceID, "meName": meName, "meEntityID": meEntityID, "attributes": attributes})
+					oo.pOnuDB.PutMe(ctx, meClassID, meEntityID, attributes)
+				}
+			}
+		}
 	} else {
 		logger.Errorw(ctx, "Omci Msg layer could not be detected", log.Fields{"device-id": oo.deviceID})
 		//as long as omci-lib does not support decoding of table attribute as 'unknown/unspecified' attribute
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
index 51f1cd3..5dc3e50 100755
--- a/internal/pkg/mib/onu_device_entry.go
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -940,6 +940,14 @@
 	return value
 }
 
+// GetPersIsExtOmciSupported - TODO: add comment
+func (oo *OnuDeviceEntry) GetPersIsExtOmciSupported() bool {
+	oo.MutexPersOnuConfig.RLock()
+	defer oo.MutexPersOnuConfig.RUnlock()
+	value := oo.SOnuPersistentData.PersIsExtOmciSupported
+	return value
+}
+
 // GetPersEquipmentID - TODO: add comment
 func (oo *OnuDeviceEntry) GetPersEquipmentID() string {
 	oo.MutexPersOnuConfig.RLock()