[VOL-3279] Resetting the GemPort when all the flows in an ONU are removed

Change-Id: Icd01703900cd14e0e3baf2abb4669524a47dbeeb
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index a2e3229..700fdeb 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -162,7 +162,7 @@
 			// create ONU devices
 			for j := 0; j < olt.NumOnuPerPon; j++ {
 				delay := time.Duration(olt.Delay*j) * time.Millisecond
-				o := CreateONU(&olt, *p, uint32(j+1), options.BBSim.STag, availableCTag, options.BBSim.EnableAuth, options.BBSim.EnableDhcp, delay, isMock)
+				o := CreateONU(&olt, p, uint32(j+1), options.BBSim.STag, availableCTag, options.BBSim.EnableAuth, options.BBSim.EnableDhcp, delay, isMock)
 				p.Onus = append(p.Onus, o)
 				availableCTag = availableCTag + 1
 			}
@@ -178,7 +178,7 @@
 			// create ONU devices
 			for j := 0; j < olt.NumOnuPerPon; j++ {
 				delay := time.Duration(olt.Delay*j) * time.Millisecond
-				o := CreateONU(&olt, *p, uint32(j+1), availableSTag, options.BBSim.CTag, options.BBSim.EnableAuth, options.BBSim.EnableDhcp, delay, isMock)
+				o := CreateONU(&olt, p, uint32(j+1), availableSTag, options.BBSim.CTag, options.BBSim.EnableAuth, options.BBSim.EnableDhcp, delay, isMock)
 				p.Onus = append(p.Onus, o)
 				availableSTag = availableSTag + 1
 			}
@@ -1046,11 +1046,11 @@
 	if flow.AccessIntfId == -1 {
 		oltLogger.WithFields(log.Fields{
 			"FlowId": flow.FlowId,
-		}).Debugf("This is an OLT flow")
+		}).Debug("Adding OLT flow")
 	} else if flow.FlowType == "multicast" {
 		oltLogger.WithFields(log.Fields{
 			"FlowId": flow.FlowId,
-		}).Debugf("This is a multicast flow")
+		}).Debug("Adding OLT multicast flow")
 	} else {
 		pon, err := o.GetPonById(uint32(flow.AccessIntfId))
 		if err != nil {
@@ -1078,7 +1078,7 @@
 		}
 
 		msg := Message{
-			Type: FlowUpdate,
+			Type: FlowAdd,
 			Data: OnuFlowUpdateMessage{
 				PonPortID: pon.ID,
 				OnuID:     onu.ID,
@@ -1093,10 +1093,11 @@
 
 // FlowRemove request from VOLTHA
 func (o OltDevice) FlowRemove(_ context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
+
 	oltLogger.WithFields(log.Fields{
-		"FlowId":   flow.FlowId,
-		"FlowType": flow.FlowType,
-	}).Tracef("OLT receives FlowRemove")
+		"FlowId":           flow.FlowId,
+		"FlowType":         flow.FlowType,
+	}).Debug("OLT receives FlowRemove")
 
 	if !o.enablePerf { // remove only if flow were stored
 		flowKey := FlowKey{
@@ -1130,6 +1131,36 @@
 		// delete from olt flows
 		delete(o.Flows, flowKey)
 	}
+
+	if flow.AccessIntfId == -1 {
+		oltLogger.WithFields(log.Fields{
+			"FlowId": flow.FlowId,
+		}).Debug("Removing OLT flow")
+	} else if flow.FlowType == "multicast" {
+		oltLogger.WithFields(log.Fields{
+			"FlowId": flow.FlowId,
+		}).Debug("Removing OLT multicast flow")
+	} else {
+
+		onu, err := o.GetOnuByFlowId(flow.FlowId)
+		if err != nil {
+			oltLogger.WithFields(log.Fields{
+				"OnuId":  flow.OnuId,
+				"IntfId": flow.AccessIntfId,
+				"err":    err,
+			}).Error("Can't find Onu")
+			return nil, err
+		}
+
+		msg := Message{
+			Type: FlowRemoved,
+			Data: OnuFlowUpdateMessage{
+				Flow:      flow,
+			},
+		}
+		onu.Channel <- msg
+	}
+
 	return new(openolt.Empty), nil
 }
 
@@ -1141,6 +1172,19 @@
 	return &res, nil
 }
 
+func (o *OltDevice) GetOnuByFlowId(flowId uint32) (*Onu, error) {
+	for _, pon := range o.Pons {
+		for _, onu := range pon.Onus {
+			for _, fId := range onu.FlowIds {
+				if fId == flowId {
+					return onu, nil
+				}
+			}
+		}
+	}
+	return nil, errors.New(fmt.Sprintf("Cannot find Onu by flowId %d", flowId))
+}
+
 func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
 
 	oltLogger.WithFields(log.Fields{