Extension for OnuAdapter reconcilement on VLAN processing for Multi-UNI support

Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: Iee3419feb8cdeec00a3a625dd15c2bbb09293016
diff --git a/VERSION b/VERSION
index 3e3c2f1..209873d 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.1.1
+2.1.2-dev252
diff --git a/internal/pkg/common/interfaces.go b/internal/pkg/common/interfaces.go
index c16f42f..d842350 100755
--- a/internal/pkg/common/interfaces.go
+++ b/internal/pkg/common/interfaces.go
@@ -147,9 +147,6 @@
 
 	AllocateFreeTcont(context.Context, uint16) (uint16, bool, error)
 	FreeTcont(context.Context, uint16)
-
-	LockMutexPersOnuConfig()
-	UnlockMutexPersOnuConfig()
 }
 
 // IonuMetricsManager interface to onuMetricsManager
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 0203575..4274e90 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -249,7 +249,6 @@
 	dh.lockUpgradeFsm = sync.RWMutex{}
 	dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
 	dh.reconciling = cNoReconciling
-	dh.chUniVlanConfigReconcilingDone = make(chan uint16)
 	dh.chReconcilingFinished = make(chan bool)
 	dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
 	rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
@@ -2717,9 +2716,14 @@
 		return
 	}
 
+	//Note: For the moment is is not required to include the (newly added) POTS ports into the range
+	//  of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
+	//  also for the POTS ports, so we include them already for future usage - should anyway do no great harm
 	dh.flowCbChan = make([]chan FlowCb, uniCnt)
 	dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
 	dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
+	//chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
+	dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
 	for i := 0; i < int(uniCnt); i++ {
 		dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
 		dh.stopFlowMonitoringRoutine[i] = make(chan bool)
@@ -3988,6 +3992,7 @@
 						logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
 							log.Fields{"device-id": dh.DeviceID})
 					} else {
+						onuDevEntry.MutexPersOnuConfig.RLock()
 						if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
 							connectStatus = voltha.ConnectStatus_REACHABLE
 							if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
@@ -4002,7 +4007,7 @@
 							onuDevEntry.SOnuPersistentData.PersOperState == "" {
 							operState = voltha.OperStatus_DISCOVERED
 						}
-
+						onuDevEntry.MutexPersOnuConfig.RUnlock()
 						logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
 					}
 					logger.Debugw(ctx, "reconciling has been finished in time",
@@ -4022,10 +4027,13 @@
 					if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
 						logger.Errorw(ctx, "No valid OnuDevice",
 							log.Fields{"device-id": dh.DeviceID})
-					} else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
-						connectStatus = voltha.ConnectStatus_REACHABLE
+					} else {
+						onuDevEntry.MutexPersOnuConfig.RLock()
+						if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
+							connectStatus = voltha.ConnectStatus_REACHABLE
+						}
+						onuDevEntry.MutexPersOnuConfig.RUnlock()
 					}
-
 					dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
 				}
 			case <-time.After(dh.reconcileExpiryComplete):
@@ -4035,8 +4043,12 @@
 				if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
 					logger.Errorw(ctx, "No valid OnuDevice",
 						log.Fields{"device-id": dh.DeviceID})
-				} else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
-					connectStatus = voltha.ConnectStatus_REACHABLE
+				} else {
+					onuDevEntry.MutexPersOnuConfig.RLock()
+					if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
+						connectStatus = voltha.ConnectStatus_REACHABLE
+					}
+					onuDevEntry.MutexPersOnuConfig.RUnlock()
 				}
 
 				dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
index a6068ec..517a94a 100755
--- a/internal/pkg/mib/onu_device_entry.go
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -195,8 +195,6 @@
 	pLastTxMeInstance                *me.ManagedEntity
 	omciMessageReceived              chan bool        //seperate channel needed by DownloadFsm
 	omciRebootMessageReceivedChannel chan cmn.Message // channel needed by reboot request
-
-	mutexTcontMap sync.RWMutex
 }
 
 //NewOnuDeviceEntry returns a new instance of a OnuDeviceEntry
@@ -851,8 +849,8 @@
 	logger.Debugw(ctx, "allocate-free-tcont", log.Fields{"device-id": oo.deviceID, "allocID": allocID,
 		"allocated-instances": oo.SOnuPersistentData.PersTcontMap})
 
-	oo.mutexTcontMap.Lock()
-	defer oo.mutexTcontMap.Unlock()
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
 	if entityID, ok := oo.SOnuPersistentData.PersTcontMap[allocID]; ok {
 		//tcont already allocated before, return the used instance-id
 		return entityID, true, nil
@@ -876,14 +874,13 @@
 		}
 	}
 	return 0, false, fmt.Errorf(fmt.Sprintf("no-free-tcont-left-for-device-%s", oo.deviceID))
-
 }
 
 // FreeTcont - TODO: add comment
 func (oo *OnuDeviceEntry) FreeTcont(ctx context.Context, allocID uint16) {
 	logger.Debugw(ctx, "free-tcont", log.Fields{"device-id": oo.deviceID, "alloc": allocID})
-	oo.mutexTcontMap.Lock()
-	defer oo.mutexTcontMap.Unlock()
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
 	delete(oo.SOnuPersistentData.PersTcontMap, allocID)
 }
 
@@ -899,18 +896,24 @@
 
 // GetPersSerialNumber - TODO: add comment
 func (oo *OnuDeviceEntry) GetPersSerialNumber() string {
+	oo.MutexPersOnuConfig.RLock()
+	defer oo.MutexPersOnuConfig.RUnlock()
 	value := oo.SOnuPersistentData.PersSerialNumber
 	return value
 }
 
 // GetPersVendorID - TODO: add comment
 func (oo *OnuDeviceEntry) GetPersVendorID() string {
+	oo.MutexPersOnuConfig.RLock()
+	defer oo.MutexPersOnuConfig.RUnlock()
 	value := oo.SOnuPersistentData.PersVendorID
 	return value
 }
 
 // GetPersEquipmentID - TODO: add comment
 func (oo *OnuDeviceEntry) GetPersEquipmentID() string {
+	oo.MutexPersOnuConfig.RLock()
+	defer oo.MutexPersOnuConfig.RUnlock()
 	value := oo.SOnuPersistentData.PersEquipmentID
 	return value
 }
@@ -950,23 +953,17 @@
 	oo.onuSwImageIndications = value
 }
 
-// LockMutexPersOnuConfig - TODO: add comment
-func (oo *OnuDeviceEntry) LockMutexPersOnuConfig() {
-	oo.MutexPersOnuConfig.Lock()
-}
-
-// UnlockMutexPersOnuConfig - TODO: add comment
-func (oo *OnuDeviceEntry) UnlockMutexPersOnuConfig() {
-	oo.MutexPersOnuConfig.Unlock()
-}
-
 // GetPersActiveSwVersion - TODO: add comment
 func (oo *OnuDeviceEntry) GetPersActiveSwVersion() string {
+	oo.MutexPersOnuConfig.RLock()
+	defer oo.MutexPersOnuConfig.RUnlock()
 	return oo.SOnuPersistentData.PersActiveSwVersion
 }
 
 // SetPersActiveSwVersion - TODO: add comment
 func (oo *OnuDeviceEntry) SetPersActiveSwVersion(value string) {
+	oo.MutexPersOnuConfig.Lock()
+	defer oo.MutexPersOnuConfig.Unlock()
 	oo.SOnuPersistentData.PersActiveSwVersion = value
 }
 
diff --git a/internal/pkg/swupg/onu_image_status.go b/internal/pkg/swupg/onu_image_status.go
index bb2d820..0da9e0b 100755
--- a/internal/pkg/swupg/onu_image_status.go
+++ b/internal/pkg/swupg/onu_image_status.go
@@ -317,21 +317,18 @@
 func (oo *OnuImageStatus) updateOnuSwImagePersistentData(ctx context.Context) {
 
 	activeImageVersion := oo.pDevEntry.GetActiveImageVersion(ctx)
-	oo.pDevEntry.LockMutexPersOnuConfig()
 	persActiveSwVersion := oo.pDevEntry.GetPersActiveSwVersion()
 	if persActiveSwVersion != activeImageVersion {
 		logger.Infow(ctx, "Active SW version has been changed at ONU - update persistent data",
 			log.Fields{"old version": persActiveSwVersion,
 				"new version": activeImageVersion, "device-id": oo.deviceID})
 		oo.pDevEntry.SetPersActiveSwVersion(activeImageVersion)
-		oo.pDevEntry.UnlockMutexPersOnuConfig()
 		if err := oo.pDeviceHandler.StorePersistentData(ctx); err != nil {
 			logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
 				log.Fields{"device-id": oo.deviceID, "err": err})
 		}
 		return
 	}
-	oo.pDevEntry.UnlockMutexPersOnuConfig()
 }
 
 func (oo *OnuImageStatus) setWaitingForResp(value bool) {