VOL-5367: Optimize the memory and cpu utilization of openonu adapter

Change-Id: I5b90f83387cbb6896e28ae95dc176e584cd836da
Signed-off-by: Praneeth Kumar Nalmas <praneeth.nalmas@radisys.com>
diff --git a/internal/pkg/almgr/alarm_manager.go b/internal/pkg/almgr/alarm_manager.go
index 218f58b..64a52ec 100755
--- a/internal/pkg/almgr/alarm_manager.go
+++ b/internal/pkg/almgr/alarm_manager.go
@@ -596,7 +596,7 @@
 			log.Fields{"device-id": am.deviceID})
 		return status.Error(codes.Unavailable, "alarm-manager-is-in-stopped-state")
 	}
-	if _, present := am.pOnuDeviceEntry.GetOnuDB().MeDb[classID][meInstance]; !present {
+	if meAttributes := am.pOnuDeviceEntry.GetOnuDB().GetMe(classID, meInstance); meAttributes == nil {
 		logger.Errorw(ctx, "me-class-instance-not-present",
 			log.Fields{"class-id": classID, "instance-id": meInstance, "device-id": am.deviceID})
 		return status.Error(codes.NotFound, "me-class-instance-not-present")
diff --git a/internal/pkg/avcfg/omci_ani_config.go b/internal/pkg/avcfg/omci_ani_config.go
index e04c850..e141efa 100755
--- a/internal/pkg/avcfg/omci_ani_config.go
+++ b/internal/pkg/avcfg/omci_ani_config.go
@@ -470,11 +470,11 @@
 						me.GemPortNetworkCtp_PriorityQueuePointerForDownStream:   loGemPortAttribs.downQueueID,
 					},
 				}
-				oFsm.pOnuDB.PutMe(ctx, me.GemPortNetworkCtpClassID, loGemPortAttribs.gemPortID, meParams.Attributes)
+				oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemPortNetworkCtpClassID, loGemPortAttribs.gemPortID, meParams.Attributes)
 				var meAttributes me.AttributeValueMap //dummy , anyways we are not going to use the values.
-				oFsm.pOnuDB.PutMe(ctx, me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID, loGemPortAttribs.gemPortID, meAttributes)
+				oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID, loGemPortAttribs.gemPortID, meAttributes)
 
-				oFsm.pOnuDB.PutMe(ctx, me.GemInterworkingTerminationPointClassID, loGemPortAttribs.gemPortID, meAttributes)
+				oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemInterworkingTerminationPointClassID, loGemPortAttribs.gemPortID, meAttributes)
 
 			}
 		}
@@ -1532,7 +1532,7 @@
 			_ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
 			return
 		}
-		oFsm.pOnuDB.PutMe(ctx, me.GemPortNetworkCtpClassID, gemPortAttribs.gemPortID, meParams.Attributes)
+		oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemPortNetworkCtpClassID, gemPortAttribs.gemPortID, meParams.Attributes)
 		// Mark the gem port to be added for Performance History monitoring
 		OnuMetricsManager := oFsm.pDeviceHandler.GetOnuMetricsManager()
 		if OnuMetricsManager != nil {
@@ -1664,7 +1664,7 @@
 			return
 		}
 		logger.Infow(ctx, "Adding GemIWTP to the ONU DB ", log.Fields{"device-id": oFsm.deviceID, "GEMID": gemPortAttribs.gemPortID})
-		oFsm.pOnuDB.PutMe(ctx, me.GemInterworkingTerminationPointClassID, gemPortAttribs.gemPortID, meParams.Attributes)
+		oFsm.pOnuDB.PutOnuSpeficMe(ctx, me.GemInterworkingTerminationPointClassID, gemPortAttribs.gemPortID, meParams.Attributes)
 
 	} //for all GemPort's of this T-Cont
 
diff --git a/internal/pkg/avcfg/onu_uni_tp.go b/internal/pkg/avcfg/onu_uni_tp.go
index c37e00c..19f8453 100755
--- a/internal/pkg/avcfg/onu_uni_tp.go
+++ b/internal/pkg/avcfg/onu_uni_tp.go
@@ -818,7 +818,7 @@
 func (onuTP *OnuUniTechProf) createAniConfigFsm(ctx context.Context, aUniID uint8, aTpID uint8,
 	apCurrentUniPort *cmn.OnuUniPort, devEvent cmn.OnuDeviceEvent, aProcessingStep uint8) error {
 	logger.Info(ctx, "createAniConfigFsm", log.Fields{"device-id": onuTP.deviceID})
-	chAniConfigFsm := make(chan cmn.Message, 2048)
+	chAniConfigFsm := make(chan cmn.Message, 2)
 	uniTPKey := uniTP{uniID: aUniID, tpID: aTpID}
 	if onuTP.onuDevice == nil {
 		logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": onuTP.deviceID})
diff --git a/internal/pkg/common/interfaces.go b/internal/pkg/common/interfaces.go
index 0001ecb..ce91062 100755
--- a/internal/pkg/common/interfaces.go
+++ b/internal/pkg/common/interfaces.go
@@ -42,6 +42,14 @@
 	RLockMutexDeviceHandlersMap()
 	RUnlockMutexDeviceHandlersMap()
 	GetDeviceHandler(string) (IdeviceHandler, bool)
+	GetONUMIBDBMap() devdb.OnuMCmnMEDBMap
+	RLockMutexMIBDatabaseMap()
+	RUnlockMutexMIBDatabaseMap()
+	LockMutexMIBDatabaseMap()
+	UnlockMutexMIBDatabaseMap()
+	FetchEntryFromMibDatabaseMap(context.Context, string) (*devdb.OnuCmnMEDB, bool)
+	CreateEntryAtMibDatabaseMap(context.Context, string) (*devdb.OnuCmnMEDB, error)
+	ResetEntryFromMibDatabaseMap(context.Context, string)
 }
 
 // IdeviceHandler interface to deviceHandler
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 460d794..319012c 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -2937,7 +2937,7 @@
 
 // createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
 func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
-	chLSFsm := make(chan cmn.Message, 2048)
+	chLSFsm := make(chan cmn.Message, 2)
 	var sFsmName string
 	if aAdminState {
 		logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
@@ -3010,7 +3010,7 @@
 // createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
 // precondition: lockUpgradeFsm is already locked from caller of this function
 func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
-	chUpgradeFsm := make(chan cmn.Message, 2048)
+	chUpgradeFsm := make(chan cmn.Message, 2)
 	var sFsmName = "OnuSwUpgradeFSM"
 	logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
 	if apDevEntry.PDevOmciCC == nil {
@@ -3461,7 +3461,7 @@
 // precondition: dh.lockVlanConfig is locked by the caller!
 func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
 	aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
-	chVlanFilterFsm := make(chan cmn.Message, 2048)
+	chVlanFilterFsm := make(chan cmn.Message, 2)
 
 	pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
 	if pDevEntry == nil {
diff --git a/internal/pkg/core/openonu.go b/internal/pkg/core/openonu.go
index 4e8374d..8028c34 100755
--- a/internal/pkg/core/openonu.go
+++ b/internal/pkg/core/openonu.go
@@ -51,6 +51,7 @@
 
 	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
 	"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
+	devdb "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
 	pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
 	"github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
 	uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
@@ -99,6 +100,8 @@
 	rpcTimeout                  time.Duration
 	maxConcurrentFlowsPerUni    int
 	skipOnuConfig               bool
+	mutexMibDatabaseMap         sync.RWMutex
+	MibDatabaseMap              devdb.OnuMCmnMEDBMap
 }
 
 // NewOpenONUAC returns a new instance of OpenONU_AC
@@ -159,6 +162,8 @@
 	openOnuAc.pFileManager = swupg.NewFileDownloadManager(ctx)
 	openOnuAc.pFileManager.SetDownloadTimeout(ctx, cfg.DownloadToAdapterTimeout)
 	openOnuAc.skipOnuConfig = cfg.SkipOnuConfig
+	openOnuAc.mutexMibDatabaseMap = sync.RWMutex{}
+	openOnuAc.MibDatabaseMap = make(map[string]*devdb.OnuCmnMEDB)
 
 	return &openOnuAc
 }
@@ -1359,3 +1364,87 @@
 	value, exist = oo.deviceHandlers[deviceID]
 	return value, exist
 }
+
+// GetONUMIBDBMap - Returns the Map corresponding to ONT type and the MIB common Instance.
+func (oo *OpenONUAC) GetONUMIBDBMap() devdb.OnuMCmnMEDBMap {
+	return oo.MibDatabaseMap
+}
+
+// RLockMutexMIBDatabaseMap acquires a read lock on the mutex associated with the MIBDatabaseMap.
+func (oo *OpenONUAC) RLockMutexMIBDatabaseMap() {
+	oo.mutexMibDatabaseMap.RLock()
+}
+
+// RUnlockMutexMIBDatabaseMap releases the read lock on the mutex associated with the MIBDatabaseMap.
+func (oo *OpenONUAC) RUnlockMutexMIBDatabaseMap() {
+	oo.mutexMibDatabaseMap.RUnlock()
+}
+
+// LockMutexMIBDatabaseMap locks the mutex associated with the MIBDatabaseMap.
+// Should be called before any operations that modify or read from the MIBDatabaseMap.
+func (oo *OpenONUAC) LockMutexMIBDatabaseMap() {
+	oo.mutexMibDatabaseMap.Lock()
+}
+
+// UnlockMutexMIBDatabaseMap unlocks the mutex associated with the MIBDatabaseMap.
+// Should be called after completing operations that require exclusive access
+// to the MIBDatabaseMap, ensuring the mutex is released for other goroutines.
+func (oo *OpenONUAC) UnlockMutexMIBDatabaseMap() {
+	oo.mutexMibDatabaseMap.Unlock()
+}
+
+// CreateEntryAtMibDatabaseMap  adds an entry to the MibDatabaseMap if it doesn't exist
+func (oo *OpenONUAC) CreateEntryAtMibDatabaseMap(ctx context.Context, key string) (*devdb.OnuCmnMEDB, error) {
+	oo.mutexMibDatabaseMap.Lock()
+	defer oo.mutexMibDatabaseMap.Unlock()
+
+	// Check if the key already exists
+	if mibEntry, exists := oo.MibDatabaseMap[key]; exists {
+		logger.Warnw(ctx, "Entry already exists in MIB Database Map", log.Fields{"remote-client": key})
+		return mibEntry, fmt.Errorf("entry already exists for key: %s", key)
+	}
+
+	value := devdb.NewOnuCmnMEDB(ctx)
+
+	logger.Infow(ctx, "Created a new Common MIB Database Entry", log.Fields{"remote-client": key})
+	oo.MibDatabaseMap[key] = value
+
+	return value, nil
+}
+
+// FetchEntryFromMibDatabaseMap fetches a references to common ME DB for a MIB Template from the MibDatabaseMap
+// If a valid entry exists returns pointer to cmnDB else returns nil.
+func (oo *OpenONUAC) FetchEntryFromMibDatabaseMap(ctx context.Context, key string) (*devdb.OnuCmnMEDB, bool) {
+	oo.mutexMibDatabaseMap.RLock()
+	defer oo.mutexMibDatabaseMap.RUnlock()
+	value, exists := oo.MibDatabaseMap[key]
+	if !exists {
+		return nil, false
+	}
+	return value, true
+
+}
+
+// ResetEntryFromMibDatabaseMap resets the ME values from the Maps.
+func (oo *OpenONUAC) ResetEntryFromMibDatabaseMap(ctx context.Context, key string) {
+	oo.mutexMibDatabaseMap.RLock()
+	onuCmnMEDB, exists := oo.MibDatabaseMap[key]
+	oo.mutexMibDatabaseMap.RUnlock()
+	if exists {
+		// Lock the MeDbLock to ensure thread-safe operation
+		onuCmnMEDB.MeDbLock.Lock()
+		defer onuCmnMEDB.MeDbLock.Unlock()
+
+		// Reset the MeDb and UnknownMeAndAttribDb maps
+		onuCmnMEDB.MeDb = make(devdb.MeDbMap)
+		onuCmnMEDB.UnknownMeAndAttribDb = make(devdb.UnknownMeAndAttribDbMap)
+
+	}
+}
+
+// DeleteEntryFromMibDatabaseMap deletes an entry from the MibDatabaseMap
+func (oo *OpenONUAC) DeleteEntryFromMibDatabaseMap(key string) {
+	oo.mutexMibDatabaseMap.Lock()
+	defer oo.mutexMibDatabaseMap.Unlock()
+	delete(oo.MibDatabaseMap, key)
+}
diff --git a/internal/pkg/devdb/onu_device_db.go b/internal/pkg/devdb/onu_device_db.go
index dc3e82d..423f0d9 100755
--- a/internal/pkg/devdb/onu_device_db.go
+++ b/internal/pkg/devdb/onu_device_db.go
@@ -29,7 +29,14 @@
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 )
 
-type meDbMap map[me.ClassID]map[uint16]me.AttributeValueMap
+// MeDbMap type holds MEs that are known to the ONT.
+type MeDbMap map[me.ClassID]map[uint16]me.AttributeValueMap
+
+// UnknownMeAndAttribDbMap type holds MEs that are Unknown to the ONT.
+type UnknownMeAndAttribDbMap map[UnknownMeOrAttribName]map[me.ClassID]map[uint16]unknownAttribs
+
+// OnuMCmnMEDBMap type holds MEs that are classified as  Unknown to the ONT.
+type OnuMCmnMEDBMap map[string]*OnuCmnMEDB
 
 // UnknownMeOrAttribName type to be used for unknown ME and attribute names
 type UnknownMeOrAttribName string
@@ -48,15 +55,44 @@
 	AttribMask  string `json:"AttributeMask"`
 	AttribBytes string `json:"AttributeBytes"`
 }
-type unknownMeAndAttribDbMap map[UnknownMeOrAttribName]map[me.ClassID]map[uint16]unknownAttribs
 
 // OnuDeviceDB structure holds information about ME's
 type OnuDeviceDB struct {
-	ctx                  context.Context
-	deviceID             string
-	MeDb                 meDbMap
-	meDbLock             sync.RWMutex
-	UnknownMeAndAttribDb unknownMeAndAttribDbMap
+	ctx                 context.Context
+	deviceID            string
+	CommonMeDb          *OnuCmnMEDB // Reference to OnuCmnMEDB
+	OnuSpecificMeDbLock sync.RWMutex
+	OnuSpecificMeDb     MeDbMap
+}
+
+// MIBUploadStatus represents the status of MIBUpload for a particular ONT.
+type MIBUploadStatus int
+
+// Values for Status of the ONT MIB Upload.
+const (
+	NotStarted MIBUploadStatus = iota // MIB upload has not started
+	InProgress                        // MIB upload is in progress
+	Failed                            // MIB upload has failed
+	Completed                         // MIB upload is completed
+)
+
+// OnuCmnMEDB structure holds information about ME's common to ONT possessing same MIB Template.
+type OnuCmnMEDB struct {
+	MeDbLock             sync.RWMutex
+	MeDb                 MeDbMap
+	UnknownMeAndAttribDb UnknownMeAndAttribDbMap
+	MIBUploadStatus      MIBUploadStatus
+}
+
+// NewOnuCmnMEDB returns a new instance of OnuCmnMEDB
+func NewOnuCmnMEDB(ctx context.Context) *OnuCmnMEDB {
+
+	return &OnuCmnMEDB{
+		MeDbLock:             sync.RWMutex{},
+		MeDb:                 make(MeDbMap),
+		UnknownMeAndAttribDb: make(UnknownMeAndAttribDbMap),
+		MIBUploadStatus:      NotStarted,
+	}
 }
 
 // NewOnuDeviceDB returns a new instance for a specific ONU_Device_Entry
@@ -65,49 +101,61 @@
 	var OnuDeviceDB OnuDeviceDB
 	OnuDeviceDB.ctx = ctx
 	OnuDeviceDB.deviceID = aDeviceID
-	OnuDeviceDB.MeDb = make(meDbMap)
-	OnuDeviceDB.UnknownMeAndAttribDb = make(unknownMeAndAttribDbMap)
+	OnuDeviceDB.CommonMeDb = nil
+	OnuDeviceDB.OnuSpecificMeDb = make(MeDbMap)
 
 	return &OnuDeviceDB
 }
 
 // PutMe puts an ME instance into internal ONU DB
 func (OnuDeviceDB *OnuDeviceDB) PutMe(ctx context.Context, meClassID me.ClassID, meEntityID uint16, meAttributes me.AttributeValueMap) {
-	OnuDeviceDB.meDbLock.Lock()
-	defer OnuDeviceDB.meDbLock.Unlock()
+
 	//filter out the OnuData
 	if me.OnuDataClassID == meClassID {
 		return
 	}
-	_, ok := OnuDeviceDB.MeDb[meClassID]
+
+	// Dereference the MeDb pointer
+	if OnuDeviceDB.CommonMeDb == nil || OnuDeviceDB.CommonMeDb.MeDb == nil {
+		logger.Errorw(ctx, "MeDb is nil", log.Fields{"device-id": OnuDeviceDB.deviceID})
+		return
+	}
+	meDb := OnuDeviceDB.CommonMeDb.MeDb
+	_, ok := meDb[meClassID]
 	if !ok {
 		logger.Debugw(ctx, "meClassID not found - add to db :", log.Fields{"device-id": OnuDeviceDB.deviceID})
-		OnuDeviceDB.MeDb[meClassID] = make(map[uint16]me.AttributeValueMap)
-		OnuDeviceDB.MeDb[meClassID][meEntityID] = make(me.AttributeValueMap)
-		OnuDeviceDB.MeDb[meClassID][meEntityID] = meAttributes
+		meDb[meClassID] = make(map[uint16]me.AttributeValueMap)
+		meDb[meClassID][meEntityID] = make(me.AttributeValueMap)
+		meDb[meClassID][meEntityID] = meAttributes
 	} else {
-		meAttribs, ok := OnuDeviceDB.MeDb[meClassID][meEntityID]
+		meAttribs, ok := meDb[meClassID][meEntityID]
 		if !ok {
-			OnuDeviceDB.MeDb[meClassID][meEntityID] = make(me.AttributeValueMap)
-			OnuDeviceDB.MeDb[meClassID][meEntityID] = meAttributes
+			meDb[meClassID][meEntityID] = make(me.AttributeValueMap)
+			meDb[meClassID][meEntityID] = meAttributes
 		} else {
 			for k, v := range meAttributes {
 				meAttribs[k] = v
 			}
-			OnuDeviceDB.MeDb[meClassID][meEntityID] = meAttribs
+			meDb[meClassID][meEntityID] = meAttribs
 		}
 	}
 }
 
 // GetMe returns an ME instance from internal ONU DB
 func (OnuDeviceDB *OnuDeviceDB) GetMe(meClassID me.ClassID, meEntityID uint16) me.AttributeValueMap {
-	OnuDeviceDB.meDbLock.RLock()
-	defer OnuDeviceDB.meDbLock.RUnlock()
-	if meAttributes, present := OnuDeviceDB.MeDb[meClassID][meEntityID]; present {
-		/* verbose logging, avoid in >= debug level
-		logger.Debugw(ctx,"ME found:", log.Fields{"meClassID": meClassID, "meEntityID": meEntityID, "meAttributes": meAttributes,
-			"device-id": OnuDeviceDB.deviceID})
-		*/
+	OnuDeviceDB.CommonMeDb.MeDbLock.RLock()
+	defer OnuDeviceDB.CommonMeDb.MeDbLock.RUnlock()
+
+	// Check in the common MeDb
+	if meAttributes, present := OnuDeviceDB.CommonMeDb.MeDb[meClassID][meEntityID]; present {
+		return meAttributes
+	}
+
+	OnuDeviceDB.OnuSpecificMeDbLock.RLock()
+	defer OnuDeviceDB.OnuSpecificMeDbLock.RUnlock()
+
+	// Check in the ONU-specific MeDb
+	if meAttributes, present := OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID]; present {
 		return meAttributes
 	}
 	return nil
@@ -145,35 +193,77 @@
 func (OnuDeviceDB *OnuDeviceDB) GetSortedInstKeys(ctx context.Context, meClassID me.ClassID) []uint16 {
 
 	var meInstKeys []uint16
-	OnuDeviceDB.meDbLock.RLock()
-	defer OnuDeviceDB.meDbLock.RUnlock()
-	meInstMap := OnuDeviceDB.MeDb[meClassID]
+	OnuDeviceDB.CommonMeDb.MeDbLock.RLock()
+	defer OnuDeviceDB.CommonMeDb.MeDbLock.RUnlock()
+	meDb := OnuDeviceDB.CommonMeDb.MeDb
 
-	for k := range meInstMap {
-		meInstKeys = append(meInstKeys, k)
+	// Check if the class ID exists in the MeDb map
+	if meInstMap, found := meDb[meClassID]; found {
+		for k := range meInstMap {
+			meInstKeys = append(meInstKeys, k)
+		}
+		logger.Debugw(ctx, "meInstKeys - input order :", log.Fields{"meInstKeys": meInstKeys}) //TODO: delete the line after test phase!
 	}
-	logger.Debugw(ctx, "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(ctx, "meInstKeys - output order :", log.Fields{"meInstKeys": meInstKeys}) //TODO: delete the line after test phase!
+
+	// Return the sorted instance keys
 	return meInstKeys
 }
 
 // GetNumberOfInst returns the number of instances of an ME
 func (OnuDeviceDB *OnuDeviceDB) GetNumberOfInst(meClassID me.ClassID) int {
-	OnuDeviceDB.meDbLock.RLock()
-	defer OnuDeviceDB.meDbLock.RUnlock()
-	return len(OnuDeviceDB.MeDb[meClassID])
+	var count int
+
+	OnuDeviceDB.CommonMeDb.MeDbLock.RLock()
+	defer OnuDeviceDB.CommonMeDb.MeDbLock.RUnlock()
+
+	if meClassMap, found := OnuDeviceDB.CommonMeDb.MeDb[meClassID]; found {
+		count = len(meClassMap)
+	}
+
+	OnuDeviceDB.OnuSpecificMeDbLock.RLock()
+	defer OnuDeviceDB.OnuSpecificMeDbLock.RUnlock()
+
+	if onuSpecificMap, found := OnuDeviceDB.OnuSpecificMeDb[meClassID]; found {
+		count += len(onuSpecificMap)
+	}
+
+	return count
 }
 
 // LogMeDb logs content of internal ONU DB
 func (OnuDeviceDB *OnuDeviceDB) LogMeDb(ctx context.Context) {
-	logger.Debugw(ctx, "ME instances stored for :", log.Fields{"device-id": OnuDeviceDB.deviceID})
-	for meClassID, meInstMap := range OnuDeviceDB.MeDb {
+	logger.Debugw(ctx, "Logging ME instances for device:", log.Fields{"device-id": OnuDeviceDB.deviceID})
+
+	if OnuDeviceDB.CommonMeDb != nil && OnuDeviceDB.CommonMeDb.MeDb != nil {
+		meDb := OnuDeviceDB.CommonMeDb.MeDb
+
+		for meClassID, meInstMap := range meDb {
+			for meEntityID, meAttribs := range meInstMap {
+				logger.Debugw(ctx, "Common ME instance: ", log.Fields{"meClassID": meClassID, "meEntityID": meEntityID, "meAttribs": meAttribs,
+					"device-id": OnuDeviceDB.deviceID})
+			}
+		}
+	} else {
+		logger.Warnw(ctx, "Common MeDb is nil", log.Fields{"device-id": OnuDeviceDB.deviceID})
+	}
+
+	// Log ONU-specific ME instances
+	OnuDeviceDB.OnuSpecificMeDbLock.RLock()
+	defer OnuDeviceDB.OnuSpecificMeDbLock.RUnlock()
+
+	for meClassID, meInstMap := range OnuDeviceDB.OnuSpecificMeDb {
 		for meEntityID, meAttribs := range meInstMap {
-			logger.Debugw(ctx, "ME instance: ", log.Fields{"meClassID": meClassID, "meEntityID": meEntityID, "meAttribs": meAttribs,
-				"device-id": OnuDeviceDB.deviceID})
+			logger.Debugw(ctx, "ONU Specific ME instance:", log.Fields{
+				"meClassID":  meClassID,
+				"meEntityID": meEntityID,
+				"meAttribs":  meAttribs,
+				"device-id":  OnuDeviceDB.deviceID,
+			})
 		}
 	}
+
 }
 
 // PutUnknownMeOrAttrib puts an instance with unknown ME or attributes into internal ONU DB
@@ -183,20 +273,22 @@
 	meAttribMaskStr := fmt.Sprintf("0x%04x", aMeAttributeMask)
 	attribs := unknownAttribs{meAttribMaskStr, hex.EncodeToString(aMePayload)}
 
-	_, ok := OnuDeviceDB.UnknownMeAndAttribDb[aMeName]
+	unknownMeDb := OnuDeviceDB.CommonMeDb.UnknownMeAndAttribDb
+
+	_, ok := unknownMeDb[aMeName]
 	if !ok {
-		OnuDeviceDB.UnknownMeAndAttribDb[aMeName] = make(map[me.ClassID]map[uint16]unknownAttribs)
-		OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID] = make(map[uint16]unknownAttribs)
-		OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID][aMeEntityID] = attribs
+		unknownMeDb[aMeName] = make(map[me.ClassID]map[uint16]unknownAttribs)
+		unknownMeDb[aMeName][aMeClassID] = make(map[uint16]unknownAttribs)
+		unknownMeDb[aMeName][aMeClassID][aMeEntityID] = attribs
 	} else {
-		_, ok := OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID]
+		_, ok := unknownMeDb[aMeName][aMeClassID]
 		if !ok {
-			OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID] = make(map[uint16]unknownAttribs)
-			OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID][aMeEntityID] = attribs
+			unknownMeDb[aMeName][aMeClassID] = make(map[uint16]unknownAttribs)
+			unknownMeDb[aMeName][aMeClassID][aMeEntityID] = attribs
 		} else {
-			_, ok := OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID][aMeEntityID]
+			_, ok := unknownMeDb[aMeName][aMeClassID][aMeEntityID]
 			if !ok {
-				OnuDeviceDB.UnknownMeAndAttribDb[aMeName][aMeClassID][aMeEntityID] = attribs
+				unknownMeDb[aMeName][aMeClassID][aMeEntityID] = attribs
 			}
 		}
 	}
@@ -204,7 +296,40 @@
 
 // DeleteMe deletes an ME instance from internal ONU DB
 func (OnuDeviceDB *OnuDeviceDB) DeleteMe(meClassID me.ClassID, meEntityID uint16) {
-	OnuDeviceDB.meDbLock.Lock()
-	defer OnuDeviceDB.meDbLock.Unlock()
-	delete(OnuDeviceDB.MeDb[meClassID], meEntityID)
+	OnuDeviceDB.CommonMeDb.MeDbLock.Lock()
+	defer OnuDeviceDB.CommonMeDb.MeDbLock.Unlock()
+	meDb := OnuDeviceDB.CommonMeDb.MeDb
+	delete(meDb[meClassID], meEntityID)
+
+	OnuDeviceDB.OnuSpecificMeDbLock.Lock()
+	defer OnuDeviceDB.OnuSpecificMeDbLock.Unlock()
+	delete(OnuDeviceDB.OnuSpecificMeDb[meClassID], meEntityID)
+}
+
+// PutOnuSpeficMe puts an ME instance into specifically to the ONU DB maintained per ONU.
+func (OnuDeviceDB *OnuDeviceDB) PutOnuSpeficMe(ctx context.Context, meClassID me.ClassID, meEntityID uint16, meAttributes me.AttributeValueMap) {
+	OnuDeviceDB.OnuSpecificMeDbLock.Lock()
+	defer OnuDeviceDB.OnuSpecificMeDbLock.Unlock()
+	//filter out the OnuData
+	if me.OnuDataClassID == meClassID {
+		return
+	}
+	_, ok := OnuDeviceDB.OnuSpecificMeDb[meClassID]
+	if !ok {
+		logger.Debugw(ctx, "meClassID not found - add to db :", log.Fields{"device-id": OnuDeviceDB.deviceID})
+		OnuDeviceDB.OnuSpecificMeDb[meClassID] = make(map[uint16]me.AttributeValueMap)
+		OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID] = make(me.AttributeValueMap)
+		OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID] = meAttributes
+	} else {
+		meAttribs, ok := OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID]
+		if !ok {
+			OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID] = make(me.AttributeValueMap)
+			OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID] = meAttributes
+		} else {
+			for k, v := range meAttributes {
+				meAttribs[k] = v
+			}
+			OnuDeviceDB.OnuSpecificMeDb[meClassID][meEntityID] = meAttribs
+		}
+	}
 }
diff --git a/internal/pkg/mib/mib_sync.go b/internal/pkg/mib/mib_sync.go
index 9353d90..2e71364 100755
--- a/internal/pkg/mib/mib_sync.go
+++ b/internal/pkg/mib/mib_sync.go
@@ -306,25 +306,44 @@
 		logger.Errorw(ctx, "get-mib-template: no active SW version found, working with empty SW version, which might be untrustworthy",
 			log.Fields{"device-id": oo.deviceID})
 	}
-	if oo.getMibFromTemplate(ctx) {
-		logger.Debug(ctx, "MibSync FSM - valid MEs stored from template")
-		oo.pOnuDB.LogMeDb(ctx)
-		fsmMsg = cmn.LoadMibTemplateOk
-	} else {
-		logger.Debug(ctx, "MibSync FSM - no valid MEs stored from template - perform MIB-upload!")
-		fsmMsg = cmn.LoadMibTemplateFailed
 
+	//create the MIB Template path
+	oo.mibTemplatePath = oo.buildMibTemplatePath()
+
+	if cmnMEDBVal, exist := oo.pOpenOnuAc.FetchEntryFromMibDatabaseMap(ctx, oo.mibTemplatePath); exist {
+		logger.Infow(ctx, "A Common MIB DB Instance exist for this type of ONT", log.Fields{"device-id": oo.deviceID, "mibTemplatePath": oo.mibTemplatePath})
 		oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
-		if mibTemplateIsGenerated, exist := oo.pOpenOnuAc.GetMibTemplatesGenerated(oo.mibTemplatePath); exist {
-			if mibTemplateIsGenerated {
-				logger.Debugw(ctx,
-					"MibSync FSM - template was successfully generated before, but doesn't exist or isn't usable anymore - reset flag in map",
-					log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
-				oo.pOpenOnuAc.SetMibTemplatesGenerated(oo.mibTemplatePath, false)
-			}
+		oo.pOnuDB.CommonMeDb = cmnMEDBVal
+
+		if cmnMEDBVal.MIBUploadStatus == devdb.Completed {
+			oo.pOnuDB.CommonMeDb.MeDbLock.Lock()
+			oo.updateOnuSpecificEntries(ctx)
+			oo.pOnuDB.CommonMeDb.MeDbLock.Unlock()
+			fsmMsg = cmn.LoadMibTemplateOk
+		} else {
+			logger.Errorw(ctx, "A previous MIB Upload for this type of ONT  has failed, request for a MIB UPload", log.Fields{"device-id": oo.deviceID})
+			oo.pOpenOnuAc.ResetEntryFromMibDatabaseMap(ctx, oo.mibTemplatePath)
+			fsmMsg = cmn.LoadMibTemplateFailed
 		}
 		oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
+
+	} else {
+		Value, err := oo.mibTemplateKVStore.Get(log.WithSpanFromContext(context.TODO(), ctx), oo.mibTemplatePath)
+		if err == nil && Value != nil {
+			logger.Infow(ctx, "No Common MIB DB instance  exist , creating from Template", log.Fields{"device-id": oo.deviceID, "mibTemplatePath": oo.mibTemplatePath})
+			oo.processMibTemplate(ctx, Value)
+		} else {
+			logger.Infow(ctx, "Neither  Common MIB  DB  Instance nor MIB template exist for this type of ONT", log.Fields{"device-id": oo.deviceID, "mibTemplatePath": oo.mibTemplatePath})
+			oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
+			cmnMEDBValue, _ := oo.pOpenOnuAc.CreateEntryAtMibDatabaseMap(ctx, oo.mibTemplatePath)
+			oo.pOnuDB.CommonMeDb = cmnMEDBValue
+			oo.pOnuDB.CommonMeDb.MeDbLock.Lock()
+			fsmMsg = cmn.LoadMibTemplateFailed
+
+		}
+
 	}
+
 	mibSyncMsg := cmn.Message{
 		Type: cmn.TestMsg,
 		Data: cmn.TestMessage{
@@ -774,6 +793,15 @@
 			logger.Errorw(ctx, "MibSync - MibTemplate - Failed to create and persist the mib template", log.Fields{"error": err, "device-id": oo.deviceID})
 		}
 
+		oo.updateOnuSpecificEntries(ctx)
+		logger.Errorw(ctx, "MibSync - Updtaed the ONU Specific MEs ", log.Fields{"device-id": oo.deviceID})
+
+		cmnMEDB, _ := oo.pOpenOnuAc.FetchEntryFromMibDatabaseMap(ctx, oo.mibTemplatePath)
+		cmnMEDB.MIBUploadStatus = devdb.Completed
+		oo.pOnuDB.CommonMeDb.MeDbLock.Unlock()
+		oo.pOpenOnuAc.SetMibTemplatesGenerated(oo.mibTemplatePath, true)
+		oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
+
 		_ = oo.PMibUploadFsm.PFsm.Event(UlEvSuccess)
 	}
 }
@@ -1241,29 +1269,35 @@
 	logger.Debugw(ctx, "MibSync - MibTemplate - path name", log.Fields{"path": oo.mibTemplatePath,
 		"device-id": oo.deviceID})
 
-	oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
-	if mibTemplateIsGenerated, exist := oo.pOpenOnuAc.GetMibTemplatesGenerated(oo.mibTemplatePath); exist {
-		if mibTemplateIsGenerated {
-			logger.Debugw(ctx, "MibSync - MibTemplate - another thread has already started to generate it - skip",
-				log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
-			oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
-			return nil
-		}
-		logger.Debugw(ctx, "MibSync - MibTemplate - previous generation attempt seems to be failed - try again",
-			log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
-	} else {
-		logger.Debugw(ctx, "MibSync - MibTemplate - first ONU-instance of this kind - start generation",
-			log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
-	}
-	oo.pOpenOnuAc.SetMibTemplatesGenerated(oo.mibTemplatePath, true)
-	oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
+	//Fetch the MEs dependent on serial number and MAC address and add them to onuSpecific ME DB
+	//Modify the serial number and MAC address with generic content in the common DB.
+	knownAttributeMEDb := oo.pOnuDB.CommonMeDb.MeDb
+	for firstLevelKey, firstLevelValue := range knownAttributeMEDb {
+		classID := strconv.Itoa(int(firstLevelKey))
 
+		for secondLevelKey, secondLevelValue := range firstLevelValue {
+			switch classID {
+			case "6", "256":
+				if _, exists := secondLevelValue["SerialNumber"]; exists {
+					oo.pOnuDB.PutOnuSpeficMe(ctx, firstLevelKey, secondLevelKey, secondLevelValue)
+					secondLevelValue["SerialNumber"] = "%SERIAL_NUMBER%"
+				}
+			case "134":
+				if _, exists := secondLevelValue["MacAddress"]; exists {
+					oo.pOnuDB.PutOnuSpeficMe(ctx, firstLevelKey, secondLevelKey, secondLevelValue)
+					secondLevelValue["MacAddress"] = "%MAC_ADDRESS%"
+				}
+			}
+		}
+	}
+
+	//Create the MIB Template
 	currentTime := time.Now()
 	templateMap := make(map[string]interface{})
 	templateMap["TemplateName"] = oo.mibTemplatePath
 	templateMap["TemplateCreated"] = currentTime.Format("2006-01-02 15:04:05.000000")
 
-	firstLevelMap := oo.pOnuDB.MeDb
+	firstLevelMap := oo.pOnuDB.CommonMeDb.MeDb
 	for firstLevelKey, firstLevelValue := range firstLevelMap {
 		logger.Debugw(ctx, "MibSync - MibTemplate - firstLevelKey", log.Fields{"firstLevelKey": firstLevelKey})
 		classID := strconv.Itoa(int(firstLevelKey))
@@ -1290,24 +1324,20 @@
 		}
 		templateMap[classID] = secondLevelMap
 	}
-	unknownMeAndAttribMap := oo.pOnuDB.UnknownMeAndAttribDb
+	unknownMeAndAttribMap := oo.pOnuDB.CommonMeDb.UnknownMeAndAttribDb
 	for unknownMeAndAttribMapKey := range unknownMeAndAttribMap {
 		templateMap[string(unknownMeAndAttribMapKey)] = unknownMeAndAttribMap[unknownMeAndAttribMapKey]
 	}
 	mibTemplate, err := json.Marshal(&templateMap)
 	if err != nil {
 		logger.Errorw(ctx, "MibSync - MibTemplate - Failed to marshal mibTemplate", log.Fields{"error": err, "device-id": oo.deviceID})
-		oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
 		oo.pOpenOnuAc.SetMibTemplatesGenerated(oo.mibTemplatePath, false)
-		oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
 		return err
 	}
 	err = oo.mibTemplateKVStore.Put(log.WithSpanFromContext(context.TODO(), ctx), oo.mibTemplatePath, string(mibTemplate))
 	if err != nil {
 		logger.Errorw(ctx, "MibSync - MibTemplate - Failed to store template in etcd", log.Fields{"error": err, "device-id": oo.deviceID})
-		oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
 		oo.pOpenOnuAc.SetMibTemplatesGenerated(oo.mibTemplatePath, false)
-		oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
 		return err
 	}
 	logger.Debugw(ctx, "MibSync - MibTemplate - Stored the template to etcd", log.Fields{"device-id": oo.deviceID})
@@ -1437,60 +1467,29 @@
 		"device-id": oo.deviceID})
 
 	restoredFromMibTemplate := false
-	Value, err := oo.mibTemplateKVStore.Get(log.WithSpanFromContext(context.TODO(), ctx), oo.mibTemplatePath)
-	if err == nil {
-		if Value != nil {
-			logger.Debugf(ctx, "MibSync FSM - Mib template read: Key: %s, Value: %s  %s", Value.Key, Value.Value)
-
-			// swap out tokens with specific data
-			mibTmpString, _ := kvstore.ToString(Value.Value)
-			oo.MutexPersOnuConfig.RLock()
-			mibTmpString2 := strings.Replace(mibTmpString, "%SERIAL_NUMBER%", oo.SOnuPersistentData.PersSerialNumber, -1)
-			mibTmpString = strings.Replace(mibTmpString2, "%MAC_ADDRESS%", oo.SOnuPersistentData.PersMacAddress, -1)
-			mibTmpString2 = strings.ReplaceAll(mibTmpString, "\x00", "")
-			oo.MutexPersOnuConfig.RUnlock()
-			mibTmpBytes := []byte(mibTmpString2)
-			logger.Debugf(ctx, "MibSync FSM - Mib template tokens swapped out: %s", mibTmpBytes)
-
-			var firstLevelMap map[string]interface{}
-			if err = json.Unmarshal(mibTmpBytes, &firstLevelMap); err != nil {
-				logger.Errorw(ctx, "MibSync FSM - Failed to unmarshal template", log.Fields{"error": err, "device-id": oo.deviceID})
+	oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
+	defer oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
+	if meDbValue, ok := oo.pOpenOnuAc.FetchEntryFromMibDatabaseMap(ctx, oo.mibTemplatePath); ok {
+		logger.Infow(ctx, "Found MIB common DB Instance , copy  and use", log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
+		oo.pOnuDB.CommonMeDb = meDbValue
+		oo.updateOnuSpecificEntries(ctx)
+		restoredFromMibTemplate = true
+	} else {
+		//Create a common ME MIB Instance as it doesn't prior exists.
+		Value, err := oo.mibTemplateKVStore.Get(log.WithSpanFromContext(context.TODO(), ctx), oo.mibTemplatePath)
+		//Unmarshal the MIB template and create the entry in the ONU Common Device DB
+		if err == nil {
+			if Value != nil {
+				oo.processMibTemplate(ctx, Value)
+				restoredFromMibTemplate = true
 			} else {
-				for firstLevelKey, firstLevelValue := range firstLevelMap {
-					//logger.Debugw(ctx, "MibSync FSM - firstLevelKey", log.Fields{"firstLevelKey": firstLevelKey})
-					if uint16ValidNumber, err := strconv.ParseUint(firstLevelKey, 10, 16); err == nil {
-						meClassID := me.ClassID(uint16ValidNumber)
-						//logger.Debugw(ctx, "MibSync FSM - firstLevelKey is a number in uint16-range", log.Fields{"uint16ValidNumber": uint16ValidNumber})
-						if isSupportedClassID(meClassID) {
-							//logger.Debugw(ctx, "MibSync FSM - firstLevelKey is a supported classID", log.Fields{"meClassID": meClassID})
-							secondLevelMap := firstLevelValue.(map[string]interface{})
-							for secondLevelKey, secondLevelValue := range secondLevelMap {
-								//logger.Debugw(ctx, "MibSync FSM - secondLevelKey", log.Fields{"secondLevelKey": secondLevelKey})
-								if uint16ValidNumber, err := strconv.ParseUint(secondLevelKey, 10, 16); err == nil {
-									meEntityID := uint16(uint16ValidNumber)
-									//logger.Debugw(ctx, "MibSync FSM - secondLevelKey is a number and a valid EntityId", log.Fields{"meEntityID": meEntityID})
-									thirdLevelMap := secondLevelValue.(map[string]interface{})
-									for thirdLevelKey, thirdLevelValue := range thirdLevelMap {
-										if thirdLevelKey == "Attributes" {
-											//logger.Debugw(ctx, "MibSync FSM - thirdLevelKey refers to attributes", log.Fields{"thirdLevelKey": thirdLevelKey})
-											attributesMap := thirdLevelValue.(map[string]interface{})
-											//logger.Debugw(ctx, "MibSync FSM - attributesMap", log.Fields{"attributesMap": attributesMap})
-											oo.pOnuDB.PutMe(ctx, meClassID, meEntityID, attributesMap)
-											restoredFromMibTemplate = true
-										}
-									}
-								}
-							}
-						}
-					}
-				}
+				logger.Infow(ctx, "No MIB template found", log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
 			}
 		} else {
-			logger.Infow(ctx, "No MIB template found", log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
+			logger.Errorw(ctx, "Get from kvstore operation failed for path",
+				log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
 		}
-	} else {
-		logger.Errorf(ctx, "Get from kvstore operation failed for path",
-			log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
+
 	}
 	return restoredFromMibTemplate
 }
@@ -1564,3 +1563,90 @@
 		}
 	}
 }
+
+// Updates Serial Number and MAC Address in the database
+func (oo *OnuDeviceEntry) updateOnuSpecificEntries(ctx context.Context) {
+	knownAttributeMEDb := oo.pOnuDB.CommonMeDb.MeDb
+
+	for firstLevelKey, firstLevelValue := range knownAttributeMEDb {
+		classID := strconv.Itoa(int(firstLevelKey))
+
+		for secondLevelKey, secondLevelValue := range firstLevelValue {
+			switch classID {
+			case "6", "256":
+				oo.updateAttribute(ctx, "SerialNumber", secondLevelValue, firstLevelKey, secondLevelKey, oo.SOnuPersistentData.PersSerialNumber)
+			case "134":
+				oo.updateAttribute(ctx, "MacAddress", secondLevelValue, firstLevelKey, secondLevelKey, oo.SOnuPersistentData.PersMacAddress)
+			}
+		}
+	}
+}
+
+// Updates a specific attribute in the MIB database
+func (oo *OnuDeviceEntry) updateAttribute(ctx context.Context, attributeName string, attributesMap me.AttributeValueMap, classID me.ClassID, entityID uint16, newValue interface{}) {
+	if _, exists := attributesMap[attributeName]; exists {
+		logger.Infow(ctx, "Updating "+attributeName, log.Fields{"classID": strconv.Itoa(int(classID)), "oldValue": attributesMap[attributeName], "newValue": newValue})
+		attributeCopy := make(me.AttributeValueMap)
+		for k, v := range attributesMap {
+			attributeCopy[k] = v
+		}
+		attributeCopy[attributeName] = newValue
+		oo.pOnuDB.PutOnuSpeficMe(ctx, classID, entityID, attributeCopy)
+	} else {
+		logger.Warnw(ctx, attributeName+" key not found", log.Fields{"classID": strconv.Itoa(int(classID))})
+	}
+}
+
+// Processes the MIB template by replacing tokens and unmarshaling it
+func (oo *OnuDeviceEntry) processMibTemplate(ctx context.Context, value *kvstore.KVPair) {
+	mibTmpString, _ := kvstore.ToString(value.Value)
+	mibTmpString2 := strings.ReplaceAll(mibTmpString, "\x00", "")
+	mibTmpBytes := []byte(mibTmpString2)
+
+	logger.Debugf(ctx, "MibSync FSM - Mib template tokens swapped out: %s", mibTmpBytes)
+
+	var firstLevelMap map[string]interface{}
+	if err := json.Unmarshal(mibTmpBytes, &firstLevelMap); err != nil {
+		logger.Errorw(ctx, "MibSync FSM - Failed to unmarshal template", log.Fields{"error": err, "device-id": oo.deviceID})
+		return
+	}
+
+	cmnMEDbValue, _ := oo.pOpenOnuAc.CreateEntryAtMibDatabaseMap(ctx, oo.mibTemplatePath)
+	oo.populateMibDatabase(ctx, cmnMEDbValue, firstLevelMap)
+	cmnMEDbValue.MIBUploadStatus = devdb.Completed
+	oo.pOnuDB.CommonMeDb = cmnMEDbValue
+}
+
+// Populates the MIB database with parsed data
+func (oo *OnuDeviceEntry) populateMibDatabase(ctx context.Context, cmnMEDbValue *devdb.OnuCmnMEDB, firstLevelMap map[string]interface{}) {
+	cmnMEDbValue.MeDbLock.Lock()
+	defer cmnMEDbValue.MeDbLock.Unlock()
+
+	logger.Infow(ctx, "Populating MIbDatabase with the template information ", log.Fields{"device-id": oo.deviceID})
+	for firstLevelKey, firstLevelValue := range firstLevelMap {
+		if uint16ValidNumber, err := strconv.ParseUint(firstLevelKey, 10, 16); err == nil {
+			meClassID := me.ClassID(uint16ValidNumber)
+			if isSupportedClassID(meClassID) {
+				secondLevelMap := firstLevelValue.(map[string]interface{})
+				for secondLevelKey, secondLevelValue := range secondLevelMap {
+					if uint16ValidNumber, err := strconv.ParseUint(secondLevelKey, 10, 16); err == nil {
+						meEntityID := uint16(uint16ValidNumber)
+						thirdLevelMap := secondLevelValue.(map[string]interface{})
+						if attributes, exists := thirdLevelMap["Attributes"].(map[string]interface{}); exists {
+							if _, found := cmnMEDbValue.MeDb[meClassID]; !found {
+								cmnMEDbValue.MeDb[meClassID] = make(map[uint16]me.AttributeValueMap)
+							}
+							if _, found := cmnMEDbValue.MeDb[meClassID][meEntityID]; !found {
+								cmnMEDbValue.MeDb[meClassID][meEntityID] = make(me.AttributeValueMap)
+							}
+							for attrKey, attrValue := range attributes {
+								cmnMEDbValue.MeDb[meClassID][meEntityID][attrKey] = attrValue
+							}
+						}
+
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
index 2f5f656..1b7303a 100755
--- a/internal/pkg/mib/onu_device_entry.go
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -238,7 +238,7 @@
 	onuDeviceEntry.chReconcilingFlowsFinished = make(chan bool)
 	onuDeviceEntry.reconcilingFlows = false
 	onuDeviceEntry.chOnuKvProcessingStep = make(chan uint8)
-	onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan cmn.Message, 2048)
+	onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan cmn.Message, 2)
 	//openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
 	//OMCI related databases are on a per-agent basis. State machines and tasks
 	//are per ONU Vendor
@@ -289,7 +289,7 @@
 	//onuDeviceEntry.mibNextDbResync = 0
 
 	// Omci related Mib upload sync state machine
-	mibUploadChan := make(chan cmn.Message, 2048)
+	mibUploadChan := make(chan cmn.Message, 2)
 	onuDeviceEntry.PMibUploadFsm = cmn.NewAdapterFsm("MibUpload", onuDeviceEntry.deviceID, mibUploadChan)
 	onuDeviceEntry.PMibUploadFsm.PFsm = fsm.NewFSM(
 		UlStDisabled,
@@ -376,7 +376,7 @@
 		},
 	)
 	// Omci related Mib download state machine
-	mibDownloadChan := make(chan cmn.Message, 2048)
+	mibDownloadChan := make(chan cmn.Message, 2)
 	onuDeviceEntry.PMibDownloadFsm = cmn.NewAdapterFsm("MibDownload", onuDeviceEntry.deviceID, mibDownloadChan)
 	onuDeviceEntry.PMibDownloadFsm.PFsm = fsm.NewFSM(
 		DlStDisabled,
@@ -1068,3 +1068,16 @@
 	logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": oo.deviceID})
 	_ = oo.eventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_COMMUNICATION, voltha.EventSubCategory_ONU, time.Now().Unix())
 }
+
+// IsMIBTemplateGenerated checks if a MIB Template is already present for this type of ONT.
+func (oo *OnuDeviceEntry) IsMIBTemplateGenerated(ctx context.Context) bool {
+
+	oo.pOpenOnuAc.LockMutexMibTemplateGenerated()
+	defer oo.pOpenOnuAc.UnlockMutexMibTemplateGenerated()
+
+	if _, exist := oo.pOpenOnuAc.GetMibTemplatesGenerated(oo.mibTemplatePath); !exist {
+		logger.Infow(ctx, "MIB template not Generated , further proceed to do MIB sync upload ", log.Fields{"path": oo.mibTemplatePath, "device-id": oo.deviceID})
+		return false
+	}
+	return true
+}
diff --git a/internal/pkg/pmmgr/onu_metrics_manager.go b/internal/pkg/pmmgr/onu_metrics_manager.go
index 7032fa8..f7e43c5 100755
--- a/internal/pkg/pmmgr/onu_metrics_manager.go
+++ b/internal/pkg/pmmgr/onu_metrics_manager.go
@@ -2846,7 +2846,7 @@
 			logger.Warnw(ctx, "error calling event", log.Fields{"device-id": mm.deviceID, "err": err})
 		}
 	}()
-	mm.pOnuDeviceEntry.GetOnuDB().PutMe(ctx, me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID, gemPortNTPInstID, meAttributes)
+	mm.pOnuDeviceEntry.GetOnuDB().PutOnuSpeficMe(ctx, me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID, gemPortNTPInstID, meAttributes)
 }
 
 // RemoveGemPortForPerfMonitoring - TODO: add comment