VOL-3614 Other multicast ME created after multicast gem detected.
Change-Id: Idc272aa9f6ae3c8da3910031bc226847f253a78f
diff --git a/internal/pkg/onuadaptercore/omci_ani_config.go b/internal/pkg/onuadaptercore/omci_ani_config.go
index 70b5f67..2cef989 100644
--- a/internal/pkg/onuadaptercore/omci_ani_config.go
+++ b/internal/pkg/onuadaptercore/omci_ani_config.go
@@ -307,10 +307,10 @@
mapGemPortParams := oFsm.pUniTechProf.mapPonAniConfig[oFsm.uniTpKey].mapGemPortParams
oFsm.pUniTechProf.mutexTPState.Unlock()
- loGemPortAttribs := ponAniGemPortAttribs{}
//for all TechProfile set GemIndices
-
for _, gemEntry := range mapGemPortParams {
+ loGemPortAttribs := ponAniGemPortAttribs{}
+
//collect all GemConfigData in a separate Fsm related slice (needed also to avoid mix-up with unsorted mapPonAniConfig)
if queueInstKeys := oFsm.pOnuDB.getSortedInstKeys(me.PriorityQueueClassID); len(queueInstKeys) > 0 {
@@ -368,23 +368,30 @@
loGemPortAttribs.weight = gemEntry.queueWeight
loGemPortAttribs.pbitString = gemEntry.pbitString
if gemEntry.isMulticast {
+ //TODO this might effectively ignore the for loop starting at line 316
+ loGemPortAttribs.gemPortID = gemEntry.multicastGemPortID
loGemPortAttribs.isMulticast = true
loGemPortAttribs.multicastGemID = gemEntry.multicastGemPortID
loGemPortAttribs.staticACL = gemEntry.staticACL
loGemPortAttribs.dynamicACL = gemEntry.dynamicACL
- }
- logger.Debugw("prio-related GemPort attributes:", log.Fields{
- "gemPortID": loGemPortAttribs.gemPortID,
- "upQueueID": loGemPortAttribs.upQueueID,
- "downQueueID": loGemPortAttribs.downQueueID,
- "pbitString": loGemPortAttribs.pbitString,
- "prioQueueIndex": gemEntry.prioQueueIndex,
- "isMulticast": loGemPortAttribs.isMulticast,
- "multicastGemID": loGemPortAttribs.multicastGemID,
- "staticACL": loGemPortAttribs.staticACL,
- "dynamicACL": loGemPortAttribs.dynamicACL,
- })
+ logger.Debugw("Multicast GemPort attributes:", log.Fields{
+ "gemPortID": loGemPortAttribs.gemPortID,
+ "isMulticast": loGemPortAttribs.isMulticast,
+ "multicastGemID": loGemPortAttribs.multicastGemID,
+ "staticACL": loGemPortAttribs.staticACL,
+ "dynamicACL": loGemPortAttribs.dynamicACL,
+ })
+
+ } else {
+ logger.Debugw("Upstream GemPort attributes:", log.Fields{
+ "gemPortID": loGemPortAttribs.gemPortID,
+ "upQueueID": loGemPortAttribs.upQueueID,
+ "downQueueID": loGemPortAttribs.downQueueID,
+ "pbitString": loGemPortAttribs.pbitString,
+ "prioQueueIndex": gemEntry.prioQueueIndex,
+ })
+ }
oFsm.gemPortAttribsSlice = append(oFsm.gemPortAttribsSlice, loGemPortAttribs)
}
@@ -493,6 +500,7 @@
}
func (oFsm *uniPonAniConfigFsm) enterSettingDot1PMapper(e *fsm.Event) {
+
logger.Debugw("uniPonAniConfigFsm Tx Set::.1pMapper with all PBits set", log.Fields{"EntitytId": 0x8042, /*cmp above*/
"toGemIw": 1024, /* cmp above */
"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
@@ -509,6 +517,18 @@
//assign the GemPorts according to the configured Prio
var loPrioGemPortArray [8]uint16
for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
+ if gemPortAttribs.isMulticast {
+ logger.Debugw("uniPonAniConfigFsm Port is Multicast, ignoring .1pMapper", log.Fields{
+ "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
+ "prioString": gemPortAttribs.pbitString})
+ continue
+ }
+ if gemPortAttribs.pbitString == "" {
+ logger.Warnw("uniPonAniConfigFsm PrioString empty string error", log.Fields{
+ "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
+ "prioString": gemPortAttribs.pbitString})
+ continue
+ }
for i := 0; i < 8; i++ {
// "lenOfPbitMap(8) - i + 1" will give i-th pbit value from LSB position in the pbit map string
if prio, err := strconv.Atoi(string(gemPortAttribs.pbitString[7-i])); err == nil {
@@ -529,39 +549,58 @@
}
}
+
var foundIwPtr = false
for index, value := range loPrioGemPortArray {
+ meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
if value != 0 {
foundIwPtr = true
- meAttribute := fmt.Sprintf("InterworkTpPointerForPBitPriority%d", index)
meParams.Attributes[meAttribute] = value
logger.Debugw("UniPonAniConfigFsm Set::1pMapper", log.Fields{
"for Prio": index,
"IwPtr": strconv.FormatInt(int64(value), 16),
"device-id": oFsm.deviceID})
+ } else {
+ // The null pointer 0xFFFF specifies that frames with the associated priority are to be discarded.
+ meParams.Attributes[meAttribute] = 0xffff
}
}
+ // The TP type value 0 also indicates bridging mapping, and the TP pointer should be set to 0xFFFF
+ meParams.Attributes["TpPointer"] = 0xffff
if !foundIwPtr {
- logger.Errorw("UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
+ logger.Debugw("UniPonAniConfigFsm no GemIwPtr found for .1pMapper - abort", log.Fields{
"device-id": oFsm.deviceID})
+ //TODO With multicast is possible that no upstream gem ports are not present in the tech profile,
+ // this reset needs to be performed only if the tech profile provides upstream gem ports but no priority is set
//let's reset the state machine in order to release all resources now
+ //pConfigAniStateAFsm := oFsm.pAdaptFsm
+ //if pConfigAniStateAFsm != nil {
+ // // obviously calling some FSM event here directly does not work - so trying to decouple it ...
+ // go func(aPAFsm *AdapterFsm) {
+ // if aPAFsm != nil && aPAFsm.pFsm != nil {
+ // _ = aPAFsm.pFsm.Event(aniEvReset)
+ // }
+ // }(pConfigAniStateAFsm)
+ //}
+ //Moving forward the FSM as if the response was received correctly.
pConfigAniStateAFsm := oFsm.pAdaptFsm
if pConfigAniStateAFsm != nil {
// obviously calling some FSM event here directly does not work - so trying to decouple it ...
go func(aPAFsm *AdapterFsm) {
if aPAFsm != nil && aPAFsm.pFsm != nil {
- _ = aPAFsm.pFsm.Event(aniEvReset)
+ _ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxDot1pmapSResp)
}
}(pConfigAniStateAFsm)
}
+ } else {
+ meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
+ oFsm.pAdaptFsm.commChan, meParams)
+ //accept also nil as (error) return value for writing to LastTx
+ // - this avoids misinterpretation of new received OMCI messages
+ oFsm.pLastTxMeInstance = meInstance
}
- meInstance := oFsm.pOmciCC.sendSetDot1PMapperVar(context.TODO(), ConstDefaultOmciTimeout, true,
- oFsm.pAdaptFsm.commChan, meParams)
- //accept also nil as (error) return value for writing to LastTx
- // - this avoids misinterpretation of new received OMCI messages
- oFsm.pLastTxMeInstance = meInstance
}
func (oFsm *uniPonAniConfigFsm) enterAniConfigDone(e *fsm.Event) {
@@ -775,7 +814,7 @@
{ // let the FSM proceed ...
_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxMbpcdResp)
}
- case "GemPortNetworkCtp", "GemInterworkingTerminationPoint":
+ case "GemPortNetworkCtp", "GemInterworkingTerminationPoint", "MulticastGemInterworkingTerminationPoint":
{ // let aniConfig Multi-Id processing proceed by stopping the wait function
oFsm.omciMIdsResponseReceived <- true
}
@@ -823,7 +862,7 @@
_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxResetTcontResp)
}
}
- case "PriorityQueue":
+ case "PriorityQueue", "MulticastGemInterworkingTerminationPoint":
{ // let the PrioQueue init proceed by stopping the wait function
oFsm.omciMIdsResponseReceived <- true
}
@@ -961,27 +1000,46 @@
//TODO if the port has only downstream direction the isMulticast flag can be removed.
if gemPortAttribs.isMulticast {
- ipv4MulticastTable := make([]uint8, 12)
- binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.gemPortID)
- binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
- // This is the 224.0.0.1 address
- binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4allsys))
- // this is the 255.255.255.255 address
- binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4bcast))
meParams := me.ParamData{
- EntityID: gemPortAttribs.gemPortID,
+ EntityID: gemPortAttribs.multicastGemID,
Attributes: me.AttributeValueMap{
- "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.gemPortID,
+ "GemPortNetworkCtpConnectivityPointer": gemPortAttribs.multicastGemID,
"InterworkingOption": 0, // Don't Care
"ServiceProfilePointer": 0, // Don't Care
"GalProfilePointer": galEthernetEID,
- "Ipv4MulticastAddressTable": ipv4MulticastTable,
},
}
meInstance := oFsm.pOmciCC.sendCreateMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
true, oFsm.pAdaptFsm.commChan, meParams)
oFsm.pLastTxMeInstance = meInstance
+ //verify response
+ err := oFsm.waitforOmciResponse()
+ if err != nil {
+ logger.Errorw("GemTP IW multicast create failed, aborting AniConfig FSM!",
+ log.Fields{"device-id": oFsm.deviceID, "GemIndex": gemIndex})
+ _ = oFsm.pAdaptFsm.pFsm.Event(aniEvReset)
+ return
+ }
+ ipv4MulticastTable := make([]uint8, 12)
+ //Gem Port ID
+ binary.BigEndian.PutUint16(ipv4MulticastTable[0:], gemPortAttribs.multicastGemID)
+ //Secondary Key
+ binary.BigEndian.PutUint16(ipv4MulticastTable[2:], 0)
+ // Multicast IP range start This is the 224.0.0.1 address
+ binary.BigEndian.PutUint32(ipv4MulticastTable[4:], IPToInt32(net.IPv4(224, 0, 0, 0)))
+ // MulticastIp range stop
+ binary.BigEndian.PutUint32(ipv4MulticastTable[8:], IPToInt32(net.IPv4(239, 255, 255, 255)))
+
+ meIPV4MCTableParams := me.ParamData{
+ EntityID: gemPortAttribs.multicastGemID,
+ Attributes: me.AttributeValueMap{
+ "Ipv4MulticastAddressTable": ipv4MulticastTable,
+ },
+ }
+ meIPV4MCTableInstance := oFsm.pOmciCC.sendSetMulticastGemIWTPVar(context.TODO(), ConstDefaultOmciTimeout,
+ true, oFsm.pAdaptFsm.commChan, meIPV4MCTableParams)
+ oFsm.pLastTxMeInstance = meIPV4MCTableInstance
} else {
meParams := me.ParamData{
@@ -1020,6 +1078,12 @@
//find all upstream PrioQueues related to this T-Cont
loQueueMap := ordered_map.NewOrderedMap()
for _, gemPortAttribs := range oFsm.gemPortAttribsSlice {
+ if gemPortAttribs.isMulticast {
+ logger.Debugw("uniPonAniConfigFsm Port is Multicast, ignoring PQs", log.Fields{
+ "device-id": oFsm.deviceID, "GemPort": gemPortAttribs.gemPortID,
+ "prioString": gemPortAttribs.pbitString})
+ continue
+ }
if gemPortAttribs.qosPolicy == "WRR" {
if _, ok := loQueueMap.Get(gemPortAttribs.upQueueID); !ok {
//key does not yet exist