VOL-4131 Deleted Traffic Descriptor ME when GEM Port Network CTP. If the traffic descriptor ME doesn't delete on ONU then ONU will remember the old bandwidth.

Change-Id: I5b7a4f33263983e5871965c841e4aeea2d5b9255
diff --git a/internal/pkg/onuadaptercore/omci_ani_config.go b/internal/pkg/onuadaptercore/omci_ani_config.go
index 9cb7e4c..340dd1b 100644
--- a/internal/pkg/onuadaptercore/omci_ani_config.go
+++ b/internal/pkg/onuadaptercore/omci_ani_config.go
@@ -52,6 +52,7 @@
 	aniEvFlowRemDone       = "aniEvFlowRemDone"
 	aniEvRxRemGemiwResp    = "aniEvRxRemGemiwResp"
 	aniEvRxRemGemntpResp   = "aniEvRxRemGemntpResp"
+	aniEvRxRemTdResp       = "aniEvRxRemTdResp"
 	aniEvRemTcontPath      = "aniEvRemTcontPath"
 	aniEvRxResetTcontResp  = "aniEvRxResetTcontResp"
 	aniEvRxRem1pMapperResp = "aniEvRxRem1pMapperResp"
@@ -77,6 +78,7 @@
 	aniStRemovingGemIW       = "aniStRemovingGemIW"
 	aniStWaitingFlowRem      = "aniStWaitingFlowRem"
 	aniStRemovingGemNCTP     = "aniStRemovingGemNCTP"
+	aniStRemovingTD          = "aniStRemovingTD"
 	aniStResetTcont          = "aniStResetTcont"
 	aniStRemDot1PMapper      = "aniStRemDot1PMapper"
 	aniStRemAniBPCD          = "aniStRemAniBPCD"
@@ -182,7 +184,8 @@
 			{Name: aniEvWaitFlowRem, Src: []string{aniStRemovingGemIW}, Dst: aniStWaitingFlowRem},
 			{Name: aniEvFlowRemDone, Src: []string{aniStWaitingFlowRem}, Dst: aniStRemovingGemIW},
 			{Name: aniEvRxRemGemiwResp, Src: []string{aniStRemovingGemIW}, Dst: aniStRemovingGemNCTP},
-			{Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStConfigDone},
+			{Name: aniEvRxRemGemntpResp, Src: []string{aniStRemovingGemNCTP}, Dst: aniStRemovingTD},
+			{Name: aniEvRxRemTdResp, Src: []string{aniStRemovingTD}, Dst: aniStConfigDone},
 
 			//for removing TCONT related resources
 			{Name: aniEvRemTcontPath, Src: []string{aniStConfigDone}, Dst: aniStResetTcont},
@@ -191,7 +194,7 @@
 			{Name: aniEvRxRemAniBPCDResp, Src: []string{aniStRemAniBPCD}, Dst: aniStRemoveDone},
 
 			{Name: aniEvTimeoutSimple, Src: []string{aniStCreatingDot1PMapper, aniStCreatingMBPCD, aniStSettingTconts, aniStSettingDot1PMapper,
-				aniStRemovingGemIW, aniStRemovingGemNCTP,
+				aniStRemovingGemIW, aniStRemovingGemNCTP, aniStRemovingTD,
 				aniStResetTcont, aniStRemDot1PMapper, aniStRemAniBPCD, aniStRemoveDone}, Dst: aniStStarting},
 			{Name: aniEvTimeoutMids, Src: []string{
 				aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs}, Dst: aniStStarting},
@@ -199,7 +202,7 @@
 			// exceptional treatment for all states except aniStResetting
 			{Name: aniEvReset, Src: []string{aniStStarting, aniStCreatingDot1PMapper, aniStCreatingMBPCD,
 				aniStSettingTconts, aniStCreatingGemNCTPs, aniStCreatingGemIWs, aniStSettingPQs, aniStSettingDot1PMapper,
-				aniStConfigDone, aniStRemovingGemIW, aniStWaitingFlowRem, aniStRemovingGemNCTP,
+				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},
@@ -220,6 +223,7 @@
 			("enter_" + aniStRemovingGemIW):       func(e *fsm.Event) { instFsm.enterRemovingGemIW(ctx, e) },
 			("enter_" + aniStWaitingFlowRem):      func(e *fsm.Event) { instFsm.enterWaitingFlowRem(ctx, e) },
 			("enter_" + aniStRemovingGemNCTP):     func(e *fsm.Event) { instFsm.enterRemovingGemNCTP(ctx, e) },
+			("enter_" + aniStRemovingTD):          func(e *fsm.Event) { instFsm.enterRemovingTD(ctx, e) },
 			("enter_" + aniStResetTcont):          func(e *fsm.Event) { instFsm.enterResettingTcont(ctx, e) },
 			("enter_" + aniStRemDot1PMapper):      func(e *fsm.Event) { instFsm.enterRemoving1pMapper(ctx, e) },
 			("enter_" + aniStRemAniBPCD):          func(e *fsm.Event) { instFsm.enterRemovingAniBPCD(ctx, e) },
@@ -929,6 +933,36 @@
 		oFsm.pDeviceHandler.pOnuMetricsMgr.RemoveGemPortForPerfMonitoring(ctx, loGemPortID)
 	}
 }
+func (oFsm *uniPonAniConfigFsm) enterRemovingTD(ctx context.Context, e *fsm.Event) {
+	oFsm.pUniTechProf.mutexTPState.Lock()
+	loGemPortID := (*(oFsm.pUniTechProf.mapRemoveGemEntry[oFsm.uniTpKey])).gemPortID
+	oFsm.pUniTechProf.mutexTPState.Unlock()
+	logger.Debugw(ctx, "uniPonAniConfigFsm - start removing Traffic Descriptor", log.Fields{
+		"device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
+		"TD-entity-id": loGemPortID})
+
+	oFsm.mutexPLastTxMeInstance.Lock()
+	meInstance, err := oFsm.pOmciCC.sendDeleteTD(log.WithSpanFromContext(context.TODO(), ctx),
+		oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, loGemPortID)
+
+	if err != nil {
+		logger.Errorw(ctx, "TD delete failed - proceed fsm",
+			log.Fields{"device-id": oFsm.deviceID, "gemPortID": loGemPortID})
+		pConfigAniStateAFsm := oFsm.pAdaptFsm
+		if pConfigAniStateAFsm != nil {
+			oFsm.mutexPLastTxMeInstance.Unlock()
+			// 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)
+			return
+		}
+	}
+	oFsm.pLastTxMeInstance = meInstance
+	oFsm.mutexPLastTxMeInstance.Unlock()
+}
 
 func (oFsm *uniPonAniConfigFsm) enterResettingTcont(ctx context.Context, e *fsm.Event) {
 	logger.Debugw(ctx, "uniPonAniConfigFsm - start resetting the TCont", log.Fields{
@@ -1302,6 +1336,11 @@
 					oFsm.mutexPLastTxMeInstance.RUnlock()
 					_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemGemntpResp)
 				}
+			case "TrafficDescriptor":
+				{ // let the FSM proceed ...
+					oFsm.mutexPLastTxMeInstance.RUnlock()
+					_ = oFsm.pAdaptFsm.pFsm.Event(aniEvRxRemTdResp)
+				}
 			case "Ieee8021PMapperServiceProfile":
 				{ // let the FSM proceed ...
 					oFsm.mutexPLastTxMeInstance.RUnlock()