[VOL-4429] openonuAdapterGo - omci config error and crash during flow removal after adapter restart

Change-Id: I82ae96e1e1dd0617689ce56226fd70c9c3c76256
diff --git a/VERSION b/VERSION
index 22122db..92ee6ac 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.14
\ No newline at end of file
+1.3.15
\ No newline at end of file
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 6c34298..c737e74 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -2122,7 +2122,7 @@
 				dh.lockVlanConfig.RUnlock()
 				//reset of all Fsm is always accompanied by global persistency data removal
 				//  no need to remove specific data
-				pVlanFilterFsm.RequestClearPersistency(false)
+				pVlanFilterFsm.RequestClearPersistency(ctx, false)
 				//ensure the FSM processing is stopped in case waiting for some response
 				pVlanFilterFsm.CancelProcessing(ctx)
 			} else {
@@ -3227,7 +3227,7 @@
 		pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
 		if pVlanFilterStatemachine != nil {
 			//if this was an event of the TP processing that was waited for in the VlanFilterFsm
-			if pVlanFilterFsm.GetWaitingTpID() == aTpID {
+			if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
 				if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
 					if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
 						logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
@@ -3892,3 +3892,11 @@
 			log.Fields{"device-id": dh.deviceID, "Err": err})
 	}
 }
+
+// GetUniVlanConfigFsm - returns pointer to UniVlanConfigFsm
+func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) *UniVlanConfigFsm {
+	dh.lockVlanConfig.RLock()
+	value := dh.UniVlanConfigFsmMap[uniID]
+	dh.lockVlanConfig.RUnlock()
+	return value
+}
diff --git a/internal/pkg/onuadaptercore/omci_ani_config.go b/internal/pkg/onuadaptercore/omci_ani_config.go
index f617f41..e6f8680 100644
--- a/internal/pkg/onuadaptercore/omci_ani_config.go
+++ b/internal/pkg/onuadaptercore/omci_ani_config.go
@@ -771,9 +771,10 @@
 	default:
 	}
 
-	if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID] != nil {
+	uniVlanConfigFsm := oFsm.pDeviceHandler.GetUniVlanConfigFsm(oFsm.pOnuUniPort.uniID)
+	if uniVlanConfigFsm != nil {
 		// ensure mutexTPState not locked before calling some VlanConfigFsm activity (that might already be pending on it)
-		if oFsm.pDeviceHandler.UniVlanConfigFsmMap[oFsm.pOnuUniPort.uniID].IsFlowRemovePending(oFsm.waitFlowDeleteChannel) {
+		if uniVlanConfigFsm.IsFlowRemovePending(ctx, oFsm.waitFlowDeleteChannel) {
 			logger.Debugw(ctx, "flow remove pending - wait before processing gem port delete",
 				log.Fields{"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID, "techProfile-id": oFsm.techProfileID})
 			// if flow remove is pending then wait for flow remove to finish first before proceeding with gem port delete
diff --git a/internal/pkg/onuadaptercore/omci_vlan_config.go b/internal/pkg/onuadaptercore/omci_vlan_config.go
index 1751cdb..01a98df 100644
--- a/internal/pkg/onuadaptercore/omci_vlan_config.go
+++ b/internal/pkg/onuadaptercore/omci_vlan_config.go
@@ -343,6 +343,8 @@
 	if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
 		oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
 	}
+	//cmp also usage in EVTOCDE create in omci_cc
+	oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
 	oFsm.numUniFlows = 1
 	oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
 
@@ -358,6 +360,10 @@
 
 //CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
 func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
+	if oFsm == nil {
+		logger.Error(ctx, "no valid UniVlanConfigFsm!")
+		return
+	}
 	//mutex protection is required for possible concurrent access to FSM members
 	oFsm.mutexIsAwaitingResponse.Lock()
 	oFsm.isCanceled = true
@@ -382,7 +388,11 @@
 }
 
 //GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
-func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
+func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
+	if oFsm == nil {
+		logger.Error(ctx, "no valid UniVlanConfigFsm!")
+		return 0
+	}
 	//mutex protection is required for possible concurrent access to FSM members
 	oFsm.mutexFlowParams.RLock()
 	defer oFsm.mutexFlowParams.RUnlock()
@@ -390,7 +400,11 @@
 }
 
 //RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
-func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
+func (oFsm *UniVlanConfigFsm) RequestClearPersistency(ctx context.Context, aClear bool) {
+	if oFsm == nil {
+		logger.Error(ctx, "no valid UniVlanConfigFsm!")
+		return
+	}
 	//mutex protection is required for possible concurrent access to FSM members
 	oFsm.mutexFlowParams.Lock()
 	defer oFsm.mutexFlowParams.Unlock()
@@ -404,6 +418,10 @@
 // nolint: gocyclo
 func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
 	aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
+	if oFsm == nil {
+		logger.Error(ctx, "no valid UniVlanConfigFsm!")
+		return fmt.Errorf("no-valid-UniVlanConfigFsm")
+	}
 	loRuleParams := uniVlanRuleParams{
 		TpID:     aTpID,
 		MatchVid: uint32(aMatchVlan),
@@ -802,6 +820,10 @@
 // if found removes cookie from flow cookie list and if this is empty
 // initiates removal of the flow related configuration from the ONU (via OMCI)
 func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
+	if oFsm == nil {
+		logger.Error(ctx, "no valid UniVlanConfigFsm!")
+		return fmt.Errorf("no-valid-UniVlanConfigFsm")
+	}
 	var deletedCookie uint64
 	flowCookieMatch := false
 	//mutex protection is required for possible concurrent access to FSM members
@@ -1117,8 +1139,6 @@
 		oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[0].Meter
 		tpID := oFsm.actualUniVlanConfigRule.TpID
 		oFsm.TpIDWaitingFor = tpID
-		//cmp also usage in EVTOCDE create in omci_cc
-		oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
 		loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
 		//attention: take care to release the mutexFlowParams when calling the FSM directly -
 		//  synchronous FSM 'event/state' functions may rely on this mutex
@@ -3101,7 +3121,11 @@
 }
 
 // IsFlowRemovePending returns true if there are pending flows to remove, else false.
-func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
+func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
+	if oFsm == nil {
+		logger.Error(ctx, "no valid UniVlanConfigFsm!")
+		return false
+	}
 	oFsm.mutexFlowParams.Lock()
 	defer oFsm.mutexFlowParams.Unlock()
 	if len(oFsm.uniRemoveFlowsSlice) > 0 {