[VOL-5448] :Onu adapter crash fix when processing pon uni config fsm

Change-Id: I1535fa2ef45491901996133870918c424eb7e379
Signed-off-by: balaji.nagarajan <balaji.nagarajan@radisys.com>
diff --git a/VERSION b/VERSION
index 404df31..562510f 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.12.22
+2.12.23
diff --git a/internal/pkg/avcfg/omci_ani_config.go b/internal/pkg/avcfg/omci_ani_config.go
index e438a71..acf5e08 100755
--- a/internal/pkg/avcfg/omci_ani_config.go
+++ b/internal/pkg/avcfg/omci_ani_config.go
@@ -42,6 +42,7 @@
 const (
 	// events of config PON ANI port FSM
 	aniEvStart             = "aniEvStart"
+	aniEvPrepareConfig     = "aniEvPrepareConfig"
 	aniEvStartConfig       = "aniEvStartConfig"
 	aniEvRxDot1pmapCResp   = "aniEvRxDot1pmapCResp"
 	aniEvRxMbpcdResp       = "aniEvRxMbpcdResp"
@@ -71,6 +72,7 @@
 	// states of config PON ANI port FSM
 	aniStDisabled            = "aniStDisabled"
 	aniStStarting            = "aniStStarting"
+	aniStPrepareConfig       = "aniStPrepareConfig"
 	aniStCreatingDot1PMapper = "aniStCreatingDot1PMapper"
 	aniStCreatingMBPCD       = "aniStCreatingMBPCD"
 	aniStSettingTconts       = "aniStSettingTconts"
@@ -195,7 +197,8 @@
 			{Name: aniEvStart, Src: []string{aniStDisabled}, Dst: aniStStarting},
 
 			//Note: .1p-Mapper and MBPCD might also have multi instances (per T-Cont) - by now only one 1 T-Cont considered!
-			{Name: aniEvStartConfig, Src: []string{aniStStarting}, Dst: aniStCreatingDot1PMapper},
+			{Name: aniEvPrepareConfig, Src: []string{aniStStarting}, Dst: aniStPrepareConfig},
+			{Name: aniEvStartConfig, Src: []string{aniStPrepareConfig}, Dst: aniStCreatingDot1PMapper},
 			{Name: aniEvRxDot1pmapCResp, Src: []string{aniStCreatingDot1PMapper}, Dst: aniStCreatingMBPCD},
 			{Name: aniEvRxMbpcdResp, Src: []string{aniStCreatingMBPCD}, Dst: aniStSettingTconts},
 			{Name: aniEvRxTcontsResp, Src: []string{aniStSettingTconts}, Dst: aniStCreatingGemNCTPs},
@@ -229,18 +232,19 @@
 				aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
 
 			// exceptional treatment for all states except aniStResetting
-			{Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
+			{Name: aniEvReset, Src: []string{aniStStarting, aniStPrepareConfig, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
 				aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
 				aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP, aniStRemovingTD,
 				aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStResetting},
 			// the only way to get to resource-cleared disabled state again is via "resseting"
 			{Name: aniEvRestart, Src: []string{aniStResetting}, Dst: aniStDisabled},
-			{Name: aniEvSkipOmciConfig, Src: []string{aniStStarting}, Dst: aniStConfigDone},
+			{Name: aniEvSkipOmciConfig, Src: []string{aniStStarting, aniStPrepareConfig}, Dst: aniStConfigDone},
 		},
 
 		fsm.Callbacks{
 			"enter_state":                         func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
 			("enter_" + aniStStarting):            func(e *fsm.Event) { instFsm.enterConfigStartingState(ctx, e) },
+			("enter_" + aniStPrepareConfig):       func(e *fsm.Event) { instFsm.prepareAndEnterConfigState(ctx, e) },
 			("enter_" + aniStCreatingDot1PMapper): func(e *fsm.Event) { instFsm.enterCreatingDot1PMapper(ctx, e) },
 			("enter_" + aniStCreatingMBPCD):       func(e *fsm.Event) { instFsm.enterCreatingMBPCD(ctx, e) },
 			("enter_" + aniStSettingTconts):       func(e *fsm.Event) { instFsm.enterSettingTconts(ctx, e) },
@@ -309,11 +313,9 @@
 	PAdaptFsm := oFsm.PAdaptFsm
 	if PAdaptFsm != nil {
 		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
-		go func(aPAFsm *cmn.AdapterFsm) {
-			if aPAFsm.PFsm != nil {
-				_ = oFsm.PAdaptFsm.PFsm.Event(aniEvReset)
-			}
-		}(PAdaptFsm)
+		if PAdaptFsm.PFsm != nil {
+			_ = PAdaptFsm.PFsm.Event(aniEvReset)
+		}
 	}
 
 	// possible access conflicts on internal data by next needed data clearance
@@ -325,9 +327,11 @@
 	oFsm.pUniTechProf.clearAniSideConfig(ctx, oFsm.pOnuUniPort.UniID, oFsm.techProfileID)
 }
 
-// nolint: gocyclo
-// TODO:visit here for refactoring for gocyclo
-func (oFsm *UniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, aPAFsm *cmn.AdapterFsm) {
+//nolint:gocyclo
+func (oFsm *UniPonAniConfigFsm) prepareAndEnterConfigState(ctx context.Context, _ *fsm.Event) {
+	logger.Info(ctx, "UniPonAniConfigFsm prepareAndEnterConfigState start", log.Fields{
+		"device-id": oFsm.deviceID})
+	aPAFsm := oFsm.PAdaptFsm
 	if aPAFsm != nil && aPAFsm.PFsm != nil {
 		var err error
 		oFsm.mapperSP0ID, err = cmn.GenerateIeeMaperServiceProfileEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.techProfileID))
@@ -480,11 +484,29 @@
 			}
 		}
 		if !oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
-			_ = aPAFsm.PFsm.Event(aniEvStartConfig)
+			//let the state machine run forward from here directly
+			if oFsm.PAdaptFsm != nil {
+				go func(aPAFsm *cmn.AdapterFsm) {
+					if aPAFsm != nil && aPAFsm.PFsm != nil {
+						_ = aPAFsm.PFsm.Event(aniEvStartConfig)
+					}
+				}(oFsm.PAdaptFsm)
+
+			}
 		} else {
 			logger.Debugw(ctx, "reconciling - skip omci-config of ANI side ", log.Fields{"device-id": oFsm.deviceID})
-			_ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
+			//let the state machine run forward from here directly
+			if oFsm.PAdaptFsm != nil {
+				go func(aPAFsm *cmn.AdapterFsm) {
+					if aPAFsm != nil && aPAFsm.PFsm != nil {
+						_ = aPAFsm.PFsm.Event(aniEvSkipOmciConfig)
+					}
+				}(oFsm.PAdaptFsm)
+
+			}
 		}
+		logger.Info(ctx, "UniPonAniConfigFsm prepareAndEnterConfigState end", log.Fields{
+			"device-id": oFsm.deviceID})
 	}
 }
 
@@ -518,7 +540,11 @@
 	pConfigAniStateAFsm := oFsm.PAdaptFsm
 	if pConfigAniStateAFsm != nil {
 		// obviously calling some FSM event here directly does not work - so trying to decouple it ...
-		go oFsm.prepareAndEnterConfigState(ctx, pConfigAniStateAFsm)
+		go func(aPAFsm *cmn.AdapterFsm) {
+			if aPAFsm != nil && aPAFsm.PFsm != nil {
+				_ = aPAFsm.PFsm.Event(aniEvPrepareConfig)
+			}
+		}(pConfigAniStateAFsm)
 
 	}
 }
diff --git a/internal/pkg/devdb/onu_device_db.go b/internal/pkg/devdb/onu_device_db.go
index f8e99cb..d299789 100755
--- a/internal/pkg/devdb/onu_device_db.go
+++ b/internal/pkg/devdb/onu_device_db.go
@@ -145,12 +145,13 @@
 // GetMe returns an ME instance from internal ONU DB
 func (OnuDeviceDB *OnuDeviceDB) GetMe(meClassID me.ClassID, meEntityID uint16) me.AttributeValueMap {
 	OnuDeviceDB.CommonMeDb.MeDbLock.RLock()
-	defer OnuDeviceDB.CommonMeDb.MeDbLock.RUnlock()
 
 	// Check in the common MeDb
 	if meAttributes, present := OnuDeviceDB.CommonMeDb.MeDb[meClassID][meEntityID]; present {
+		OnuDeviceDB.CommonMeDb.MeDbLock.RUnlock()
 		return meAttributes
 	}
+	OnuDeviceDB.CommonMeDb.MeDbLock.RUnlock()
 
 	OnuDeviceDB.OnuSpecificMeDbLock.RLock()
 	defer OnuDeviceDB.OnuSpecificMeDbLock.RUnlock()
@@ -298,9 +299,10 @@
 // DeleteMe deletes an ME instance from internal ONU DB
 func (OnuDeviceDB *OnuDeviceDB) DeleteMe(meClassID me.ClassID, meEntityID uint16) {
 	OnuDeviceDB.CommonMeDb.MeDbLock.Lock()
-	defer OnuDeviceDB.CommonMeDb.MeDbLock.Unlock()
+
 	meDb := OnuDeviceDB.CommonMeDb.MeDb
 	delete(meDb[meClassID], meEntityID)
+	OnuDeviceDB.CommonMeDb.MeDbLock.Unlock()
 
 	OnuDeviceDB.OnuSpecificMeDbLock.Lock()
 	defer OnuDeviceDB.OnuSpecificMeDbLock.Unlock()
diff --git a/internal/pkg/mib/mib_sync.go b/internal/pkg/mib/mib_sync.go
index 1481c61..036a694 100755
--- a/internal/pkg/mib/mib_sync.go
+++ b/internal/pkg/mib/mib_sync.go
@@ -818,7 +818,6 @@
 		oo.lastTxParamStruct.lastTxMessageType = omci.MibUploadNextRequestType
 		oo.mutexLastTxParamStruct.Unlock()
 	} else {
-		oo.pOnuDB.LogMeDb(ctx)
 		err := oo.createAndPersistMibTemplate(ctx)
 		if err != nil {
 			logger.Errorw(ctx, "MibSync - MibTemplate - Failed to create and persist the mib template", log.Fields{"error": err, "device-id": oo.deviceID})