[VOL-3331] Implement incremental ONU traffic flow setup request with according OMCI VLAN configuration,
now already merged with git merged patch for [VOL-3051] Create MIB template from first ONU + correction TechProfile channel processing
Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: Iabbf4e1bc16da9c115e8e4002fd328a4c6bf33fb
diff --git a/internal/pkg/onuadaptercore/onu_uni_tp.go b/internal/pkg/onuadaptercore/onu_uni_tp.go
index 728cac8..a5a8ba4 100644
--- a/internal/pkg/onuadaptercore/onu_uni_tp.go
+++ b/internal/pkg/onuadaptercore/onu_uni_tp.go
@@ -67,8 +67,9 @@
}
type tTechProfileIndication struct {
- techProfileType string
- techProfileID uint16
+ techProfileType string
+ techProfileID uint16
+ techProfileConfigDone bool
}
type tcontParamStruct struct {
@@ -100,19 +101,21 @@
//OnuUniTechProf structure holds information about the TechProfiles attached to Uni Ports of the ONU
type OnuUniTechProf struct {
- deviceID string
- baseDeviceHandler *DeviceHandler
- tpProcMutex sync.RWMutex
- mapUniTpPath map[uint32]string
- sOnuPersistentData onuPersistentData
- techProfileKVStore *db.Backend
- onuKVStore *db.Backend
- onuKVStorePath string
- chTpProcessingStep chan uint8
- mapUniTpIndication map[uint32]*tTechProfileIndication //use pointer values to ease assignments to the map
- mapPonAniConfig map[uint32]*tMapPonAniConfig //per UNI: use pointer values to ease assignments to the map
- pAniConfigFsm *UniPonAniConfigFsm
- procResult error //error indication of processing
+ deviceID string
+ baseDeviceHandler *DeviceHandler
+ tpProcMutex sync.RWMutex
+ mapUniTpPath map[uint32]string
+ sOnuPersistentData onuPersistentData
+ techProfileKVStore *db.Backend
+ onuKVStore *db.Backend
+ onuKVStorePath string
+ chTpConfigProcessingStep chan uint8
+ chTpKvProcessingStep chan uint8
+ mapUniTpIndication map[uint8]*tTechProfileIndication //use pointer values to ease assignments to the map
+ mapPonAniConfig map[uint8]*tMapPonAniConfig //per UNI: use pointer values to ease assignments to the map
+ pAniConfigFsm *UniPonAniConfigFsm
+ procResult error //error indication of processing
+ mutexTPState sync.Mutex
}
//NewOnuUniTechProf returns the instance of a OnuUniTechProf
@@ -125,9 +128,10 @@
onuTP.tpProcMutex = sync.RWMutex{}
onuTP.mapUniTpPath = make(map[uint32]string)
onuTP.sOnuPersistentData.PersUniTpPath = make([]uniPersData, 1)
- onuTP.chTpProcessingStep = make(chan uint8)
- onuTP.mapUniTpIndication = make(map[uint32]*tTechProfileIndication)
- onuTP.mapPonAniConfig = make(map[uint32]*tMapPonAniConfig)
+ onuTP.chTpConfigProcessingStep = make(chan uint8)
+ onuTP.chTpKvProcessingStep = make(chan uint8)
+ onuTP.mapUniTpIndication = make(map[uint8]*tTechProfileIndication)
+ onuTP.mapPonAniConfig = make(map[uint8]*tMapPonAniConfig)
onuTP.procResult = nil //default assumption processing done with success
onuTP.techProfileKVStore = aDeviceHandler.SetBackend(cBasePathTechProfileKVStore)
@@ -214,9 +218,9 @@
// configureUniTp checks existing tp resources to delete and starts the corresponding OMCI configuation of the UNI port
// all possibly blocking processing must be run in background to allow for deadline supervision!
// but take care on sequential background processing when needed (logical dependencies)
-// use waitForTimeoutOrCompletion(ctx, processingStep) for internal synchronisation
+// use waitForTimeoutOrCompletion(ctx, chTpConfigProcessingStep, processingStep) for internal synchronisation
func (onuTP *OnuUniTechProf) configureUniTp(ctx context.Context,
- aUniID uint32, aPathString string, wg *sync.WaitGroup) {
+ aUniID uint8, aPathString string, wg *sync.WaitGroup) {
defer wg.Done() //always decrement the waitGroup on return
logger.Debugw("configure the Uni according to TpPath", log.Fields{
"device-id": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
@@ -243,7 +247,7 @@
return
}
- var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpProcessingStep
+ var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpConfigProcessingStep
//according to updateOnuUniTpPath() logic the assumption here is, that this configuration is only called
// in case the KVPath has changed for the given UNI,
@@ -254,7 +258,7 @@
//TODO!!!:
/* if tcontMap not empty {
go onuTP.deleteAniSideConfig(ctx, aUniID, processingStep)
- if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+ if !onuTP.waitForTimeoutOrCompletion(ctx, chTpConfigProcessingStep, processingStep) {
//timeout or error detected
return
}
@@ -264,7 +268,7 @@
processingStep++
*/
go onuTP.readAniSideConfigFromTechProfile(ctx, aUniID, aPathString, processingStep)
- if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+ if !onuTP.waitForTimeoutOrCompletion(ctx, onuTP.chTpConfigProcessingStep, processingStep) {
//timeout or error detected
logger.Debugw("tech-profile related configuration aborted on read",
log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID})
@@ -277,7 +281,7 @@
if _, existTG := (*valuePA)[0]; existTG {
//Config data for this uni and and at least TCont Index 0 exist
go onuTP.setAniSideConfigFromTechProfile(ctx, aUniID, pCurrentUniPort, processingStep)
- if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+ if !onuTP.waitForTimeoutOrCompletion(ctx, onuTP.chTpConfigProcessingStep, processingStep) {
//timeout or error detected
logger.Debugw("tech-profile related configuration aborted on set",
log.Fields{"device-id": onuTP.deviceID, "UniId": aUniID})
@@ -311,9 +315,9 @@
onuTP.procResult = errors.New("ONU/TP-data update aborted: onuKVStore not set")
return
}
- var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpProcessingStep
+ var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpKvProcessingStep
go onuTP.storePersistentData(ctx, processingStep)
- if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+ if !onuTP.waitForTimeoutOrCompletion(ctx, onuTP.chTpKvProcessingStep, processingStep) {
//timeout or error detected
logger.Debugw("ONU/TP-data not written - abort", log.Fields{"device-id": onuTP.deviceID})
onuTP.procResult = errors.New("ONU/TP-data update aborted: during writing process")
@@ -355,9 +359,9 @@
//TODO!!!
//delete the given resource from ONU OMCI config and data base - as background routine
/*
- var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpProcessingStep
+ var processingStep uint8 = 1 // used to synchronize the different processing steps with chTpConfigProcessingStep
go onuTp.deleteAniResource(ctx, processingStep)
- if !onuTP.waitForTimeoutOrCompletion(ctx, processingStep) {
+ if !onuTP.waitForTimeoutOrCompletion(ctx, chTpConfigProcessingStep, processingStep) {
//timeout or error detected
return
}
@@ -387,16 +391,16 @@
if err != nil {
logger.Errorw("unable to marshal ONU/TP-data", log.Fields{"onuTP.sOnuPersistentData": onuTP.sOnuPersistentData,
"device-id": onuTP.deviceID, "err": err})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpKvProcessingStep <- 0 //error indication
return
}
err = onuTP.onuKVStore.Put(ctx, onuTP.onuKVStorePath, Value)
if err != nil {
logger.Errorw("unable to write ONU/TP-data into KVstore", log.Fields{"device-id": onuTP.deviceID, "err": err})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpKvProcessingStep <- 0 //error indication
return
}
- onuTP.chTpProcessingStep <- aProcessingStep //done
+ onuTP.chTpKvProcessingStep <- aProcessingStep //done
}
func (onuTP *OnuUniTechProf) restorePersistentData(ctx context.Context) error {
@@ -446,7 +450,7 @@
}
func (onuTP *OnuUniTechProf) readAniSideConfigFromTechProfile(
- ctx context.Context, aUniID uint32, aPathString string, aProcessingStep uint8) {
+ ctx context.Context, aUniID uint8, aPathString string, aProcessingStep uint8) {
var tpInst tp.TechProfile
//store profile type and identifier for later usage within the OMCI identifier and possibly ME setup
@@ -455,7 +459,7 @@
if len(subStringSlice) <= 2 {
logger.Errorw("invalid path name format",
log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
@@ -483,7 +487,7 @@
if err != nil {
logger.Errorw("invalid ProfileId from path",
log.Fields{"ParseErr": err})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
@@ -504,7 +508,7 @@
if err = json.Unmarshal(tpTmpBytes, &tpInst); err != nil {
logger.Errorw("TechProf - Failed to unmarshal tech-profile into tpInst",
log.Fields{"error": err, "device-id": onuTP.deviceID})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
logger.Debugw("TechProf - tpInst", log.Fields{"tpInst": tpInst})
@@ -515,13 +519,13 @@
} else {
logger.Errorw("No tech-profile found",
log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
} else {
logger.Errorw("kvstore-get failed for path",
log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
@@ -569,7 +573,7 @@
log.Fields{"device-id": onuTP.deviceID, "index": pos, "PrioQueue": content.PriorityQueue})
//remove PonAniConfig as done so far, delete map should be safe, even if not existing
delete(onuTP.mapPonAniConfig, aUniID)
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
(*(onuTP.mapPonAniConfig[aUniID]))[0].mapGemPortParams[uint16(pos)].prioQueueIndex =
@@ -594,7 +598,7 @@
log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
//remove PonAniConfig as done so far, delete map should be safe, even if not existing
delete(onuTP.mapPonAniConfig, aUniID)
- onuTP.chTpProcessingStep <- 0 //error indication
+ onuTP.chTpConfigProcessingStep <- 0 //error indication
return
}
//TODO!! MC (downstream) GemPorts can be set using DownstreamGemPortAttributeList seperately
@@ -610,15 +614,15 @@
"QueueScheduling": gemEntry.queueSchedPolicy})
}
- onuTP.chTpProcessingStep <- aProcessingStep //done
+ onuTP.chTpConfigProcessingStep <- aProcessingStep //done
}
func (onuTP *OnuUniTechProf) setAniSideConfigFromTechProfile(
- ctx context.Context, aUniID uint32, apCurrentUniPort *OnuUniPort, aProcessingStep uint8) {
+ ctx context.Context, aUniID uint8, apCurrentUniPort *OnuUniPort, aProcessingStep uint8) {
//OMCI transfer of ANI data acc. to mapPonAniConfig
// also the FSM's are running in background,
- // hence we have to make sure they indicate 'success' success on chTpProcessingStep with aProcessingStep
+ // hence we have to make sure they indicate 'success' success on chTpConfigProcessingStep with aProcessingStep
if onuTP.pAniConfigFsm == nil {
onuTP.createAniConfigFsm(aUniID, apCurrentUniPort, OmciAniConfigDone, aProcessingStep)
} else { //AniConfigFsm already init
@@ -627,13 +631,13 @@
}
func (onuTP *OnuUniTechProf) waitForTimeoutOrCompletion(
- ctx context.Context, aProcessingStep uint8) bool {
+ ctx context.Context, aChTpProcessingStep <-chan uint8, aProcessingStep uint8) bool {
select {
case <-ctx.Done():
logger.Warnw("processing not completed in-time: force release of TpProcMutex!",
log.Fields{"device-id": onuTP.deviceID, "error": ctx.Err()})
return false
- case rxStep := <-onuTP.chTpProcessingStep:
+ case rxStep := <-aChTpProcessingStep:
if rxStep == aProcessingStep {
return true
}
@@ -646,7 +650,7 @@
}
// createUniLockFsm initialises and runs the AniConfig FSM to transfer the OMCI related commands for ANI side configuration
-func (onuTP *OnuUniTechProf) createAniConfigFsm(aUniID uint32,
+func (onuTP *OnuUniTechProf) createAniConfigFsm(aUniID uint8,
apCurrentUniPort *OnuUniPort, devEvent OnuDeviceEvent, aProcessingStep uint8) {
logger.Debugw("createAniConfigFsm", log.Fields{"device-id": onuTP.deviceID})
chAniConfigFsm := make(chan Message, 2048)
@@ -676,7 +680,7 @@
if pACStatemachine != nil {
if pACStatemachine.Is(aniStDisabled) {
//FSM init requirement to get informed abou FSM completion! (otherwise timeout of the TechProf config)
- onuTP.pAniConfigFsm.SetFsmCompleteChannel(onuTP.chTpProcessingStep, aProcessingStep)
+ onuTP.pAniConfigFsm.SetFsmCompleteChannel(onuTP.chTpConfigProcessingStep, aProcessingStep)
if err := pACStatemachine.Event(aniEvStart); err != nil {
logger.Warnw("AniConfigFSM: can't start", log.Fields{"err": err})
// maybe try a FSM reset and then again ... - TODO!!!
@@ -695,3 +699,25 @@
// maybe try a FSM reset and then again ... - TODO!!!
}
}
+
+// setConfigDone sets the requested techProfile config state (if possible)
+func (onuTP *OnuUniTechProf) setConfigDone(aUniID uint8, aState bool) {
+ if _, existTP := onuTP.mapUniTpIndication[aUniID]; existTP {
+ onuTP.mutexTPState.Lock()
+ onuTP.mapUniTpIndication[aUniID].techProfileConfigDone = aState
+ onuTP.mutexTPState.Unlock()
+ } //else: the state is just ignored (does not exist)
+}
+
+// getTechProfileDone checks if the Techprofile processing with the requested TechProfile ID was done
+func (onuTP *OnuUniTechProf) getTechProfileDone(aUniID uint8, aTpID uint16) bool {
+ if _, existTP := onuTP.mapUniTpIndication[aUniID]; existTP {
+ if onuTP.mapUniTpIndication[aUniID].techProfileID == aTpID {
+ onuTP.mutexTPState.Lock()
+ defer onuTP.mutexTPState.Unlock()
+ return onuTP.mapUniTpIndication[aUniID].techProfileConfigDone
+ }
+ }
+ //for all other constellations indicate false = Config not done
+ return false
+}