WIP [VOL-3024] - MIB download - provide basic omci configuration to ONU
[VOL-3035] - Store all ME

Change-Id: Ic7393d9dd08131c17d9e4dc7cfb6d2e31bc28044
Signed-off-by: Holger Hildebrandt <holger.hildebrandt@adtran.com>
diff --git a/internal/pkg/onuadaptercore/onu_device_db.go b/internal/pkg/onuadaptercore/onu_device_db.go
index 2729747..0b985d6 100644
--- a/internal/pkg/onuadaptercore/onu_device_db.go
+++ b/internal/pkg/onuadaptercore/onu_device_db.go
@@ -19,23 +19,20 @@
 
 import (
 	"context"
-	"errors"
+	"sort"
 
 	"github.com/opencord/omci-lib-go"
 	me "github.com/opencord/omci-lib-go/generated"
 	"github.com/opencord/voltha-lib-go/v3/pkg/log"
 )
 
+type MeDbMap map[me.ClassID]map[uint16]me.AttributeValueMap
+
 //OnuDeviceDB structure holds information about known ME's
 type OnuDeviceDB struct {
-	ctx               context.Context
-	pOnuDeviceEntry   *OnuDeviceEntry
-	unigMeCount       uint16
-	unigMe            []*me.ManagedEntity
-	pptpEthUniMeCount uint16
-	pptpEthUniMe      []*me.ManagedEntity
-	AnigMe            *me.ManagedEntity
-	VeipMe            *me.ManagedEntity
+	ctx             context.Context
+	pOnuDeviceEntry *OnuDeviceEntry
+	meDb            MeDbMap
 }
 
 //OnuDeviceDB returns a new instance for a specific ONU_Device_Entry
@@ -44,91 +41,64 @@
 	var onuDeviceDB OnuDeviceDB
 	onuDeviceDB.ctx = ctx
 	onuDeviceDB.pOnuDeviceEntry = a_pOnuDeviceEntry
-	onuDeviceDB.unigMeCount = 0
-	onuDeviceDB.unigMe = make([]*me.ManagedEntity, 4, MaxUnisPerOnu)
-	onuDeviceDB.pptpEthUniMeCount = 0
-	onuDeviceDB.pptpEthUniMe = make([]*me.ManagedEntity, 4, MaxUnisPerOnu)
-	onuDeviceDB.AnigMe = nil
-	onuDeviceDB.VeipMe = nil
+	onuDeviceDB.meDb = make(MeDbMap)
+
 	return &onuDeviceDB
 }
 
-func (onuDeviceDB *OnuDeviceDB) UnigAdd(meParamData me.ParamData) error {
-	var omciErr me.OmciErrors
-	onuDeviceDB.unigMe[onuDeviceDB.unigMeCount], omciErr = me.NewUniG(meParamData)
-	if omciErr.StatusCode() != me.Success {
-		logger.Errorw("UniG could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
-		return errors.New("UniG could not be parsed")
+func (onuDeviceDB *OnuDeviceDB) StoreMe(a_pMibUpResp *omci.MibUploadNextResponse) {
+
+	meClassId := a_pMibUpResp.ReportedME.GetClassID()
+	meEntityId := a_pMibUpResp.ReportedME.GetEntityID()
+	meAttributes := a_pMibUpResp.ReportedME.GetAttributeValueMap()
+
+	//filter out the OnuData
+	if me.OnuDataClassID == meClassId {
+		return
 	}
-	logger.Debugw("UniG instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID,
-		"UnigMe ": onuDeviceDB.unigMe[onuDeviceDB.unigMeCount], "unigMeCount": onuDeviceDB.unigMeCount})
-	if onuDeviceDB.unigMeCount < MaxUnisPerOnu {
-		onuDeviceDB.unigMeCount++
+
+	logger.Debugw("Search for key data :", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "meClassId": meClassId, "meEntityId": meEntityId})
+	meInstMap, ok := onuDeviceDB.meDb[meClassId]
+	if !ok {
+		logger.Debugw("meClassId not found - add to db :", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+		meInstMap = make(map[uint16]me.AttributeValueMap)
+		onuDeviceDB.meDb[meClassId] = meInstMap
+		onuDeviceDB.meDb[meClassId][meEntityId] = meAttributes
 	} else {
-		logger.Errorw("Max number of UniGs exceeded for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
-		return errors.New("Max number of UniGs exceeded")
+		meAttribs, ok := onuDeviceDB.meDb[meClassId][meEntityId]
+		if !ok {
+			logger.Debugw("meEntityId not found - add to db :", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+			onuDeviceDB.meDb[meClassId][meEntityId] = meAttributes
+		} else {
+			logger.Debugw("ME-Instance exists already: merge attribute data :", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "meAttribs": meAttribs})
+
+			for k, v := range meAttributes {
+				meAttribs[k] = v
+			}
+			onuDeviceDB.meDb[meClassId][meEntityId] = meAttribs
+			logger.Debugw("ME-Instance updated :", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "meAttribs": meAttribs})
+		}
 	}
-	return nil
 }
 
-func (onuDeviceDB *OnuDeviceDB) PptpEthUniAdd(meParamData me.ParamData) error {
-	var omciErr me.OmciErrors
-	onuDeviceDB.pptpEthUniMe[onuDeviceDB.pptpEthUniMeCount], omciErr = me.NewPhysicalPathTerminationPointEthernetUni(meParamData)
-	if omciErr.StatusCode() != me.Success {
-		logger.Errorw("pptpEthUni could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
-		return errors.New("pptpEthUni could not be parsed")
+func (onuDeviceDB *OnuDeviceDB) GetSortedInstKeys(meInstMap map[uint16]me.AttributeValueMap) []uint16 {
+
+	var meInstKeys []uint16
+
+	for k := range meInstMap {
+		meInstKeys = append(meInstKeys, k)
 	}
-	logger.Debugw("pptpEthUni instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID,
-		"pptpEthUniMe ": onuDeviceDB.pptpEthUniMe[onuDeviceDB.pptpEthUniMeCount], "pptpEthUniMeCount": onuDeviceDB.pptpEthUniMeCount})
-	if onuDeviceDB.pptpEthUniMeCount < MaxUnisPerOnu {
-		onuDeviceDB.pptpEthUniMeCount++
-	} else {
-		logger.Errorw("Max number of pptpEthUnis exceeded for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
-		return errors.New("Max number of pptpEthUnis exceeded")
-	}
-	return nil
+	logger.Debugw("meInstKeys - input order :", log.Fields{"meInstKeys": meInstKeys}) //TODO: delete the line after test phase!
+	sort.Slice(meInstKeys, func(i, j int) bool { return meInstKeys[i] < meInstKeys[j] })
+	logger.Debugw("meInstKeys - output order :", log.Fields{"meInstKeys": meInstKeys}) //TODO: delete the line after test phase!
+	return meInstKeys
 }
 
-func (onuDeviceDB *OnuDeviceDB) AnigAdd(meParamData me.ParamData) error {
-	var omciErr me.OmciErrors
-	onuDeviceDB.AnigMe, omciErr = me.NewAniG(meParamData)
-	if omciErr.StatusCode() != me.Success {
-		logger.Errorw("AniG could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
-		return errors.New("AniG could not be parsed")
+func (onuDeviceDB *OnuDeviceDB) LogMeDb() {
+	logger.Debugw("ME instances stored for :", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+	for meClassId, meInstMap := range onuDeviceDB.meDb {
+		for meEntityId, meAttribs := range meInstMap {
+			logger.Debugw("ME instance: ", log.Fields{"meClassId": meClassId, "meEntityId": meEntityId, "meAttribs": meAttribs, "deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+		}
 	}
-	logger.Debugw("AniG instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "AnigMe ": onuDeviceDB.AnigMe})
-	return nil
-}
-
-func (onuDeviceDB *OnuDeviceDB) VeipAdd(meParamData me.ParamData) error {
-	var omciErr me.OmciErrors
-	onuDeviceDB.VeipMe, omciErr = me.NewVirtualEthernetInterfacePoint(meParamData)
-	if omciErr.StatusCode() != me.Success {
-		logger.Errorw("VEIP could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
-		return errors.New("VEIP could not be parsed")
-	}
-	logger.Debugw("VEIP instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "VeipMe ": onuDeviceDB.VeipMe})
-	return nil
-}
-
-func (onuDeviceDB *OnuDeviceDB) StoreMe(a_pMibUpResp *omci.MibUploadNextResponse) error {
-
-	meParamData := me.ParamData{
-		EntityID:   a_pMibUpResp.ReportedME.GetEntityID(),
-		Attributes: a_pMibUpResp.ReportedME.GetAttributeValueMap(),
-	}
-
-	switch a_pMibUpResp.ReportedME.GetClassID() {
-	case me.UniGClassID:
-		onuDeviceDB.UnigAdd(meParamData)
-	case me.PhysicalPathTerminationPointEthernetUniClassID:
-		onuDeviceDB.PptpEthUniAdd(meParamData)
-	case me.AniGClassID:
-		onuDeviceDB.AnigAdd(meParamData)
-	case me.VirtualEthernetInterfacePointClassID:
-		onuDeviceDB.VeipAdd(meParamData)
-	default:
-		//ME won't be stored currently
-	}
-	return nil
 }