Merge "[VOL-3942] Correctly validation flows that have ReplicateFlow set to true"
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 5e74f46..1ee67dd 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -191,7 +191,7 @@
 			"enter_state": func(e *fsm.Event) {
 				o.logStateChange(e.Src, e.Dst)
 			},
-			"enter_initialized": func(e *fsm.Event) {
+			fmt.Sprintf("enter_%s", OnuStateInitialized): func(e *fsm.Event) {
 				// create new channel for ProcessOnuMessages Go routine
 				o.Channel = make(chan bbsim.Message, 2048)
 
@@ -208,7 +208,7 @@
 					go o.ProcessOnuMessages(olt.enableContext, olt.OpenoltStream, nil)
 				}
 			},
-			"enter_discovered": func(e *fsm.Event) {
+			fmt.Sprintf("enter_%s", OnuStateDiscovered): func(e *fsm.Event) {
 				msg := bbsim.Message{
 					Type: bbsim.OnuDiscIndication,
 					Data: bbsim.OnuDiscIndicationMessage{
@@ -217,14 +217,14 @@
 				}
 				o.Channel <- msg
 			},
-			"enter_enabled": func(event *fsm.Event) {
+			fmt.Sprintf("enter_%s", OnuStateEnabled): func(event *fsm.Event) {
 
 				if used, sn := o.PonPort.isOnuIdAllocated(o.ID); used {
 					onuLogger.WithFields(log.Fields{
 						"IntfId":       o.PonPortID,
 						"OnuId":        o.ID,
 						"SerialNumber": o.Sn(),
-					}).Errorf("received-omci-with-sn-%s", common.OnuSnToString(sn))
+					}).Errorf("onu-id-duplicated-with-%s", common.OnuSnToString(sn))
 					return
 				} else {
 					o.PonPort.storeOnuId(o.ID, o.SerialNumber)
@@ -245,14 +245,9 @@
 					s.Initialize(o.PonPort.Olt.OpenoltStream)
 				}
 			},
-			"enter_disabled": func(event *fsm.Event) {
+			fmt.Sprintf("enter_%s", OnuStateDisabled): func(event *fsm.Event) {
 
-				// clean the ONU state
-				o.PortNo = 0
-				o.Flows = []FlowKey{}
-				o.PonPort.removeOnuId(o.ID)
-				o.PonPort.removeAllocId(o.SerialNumber)
-				o.PonPort.removeGemPortBySn(o.SerialNumber)
+				o.cleanupOnuState()
 
 				// set the OperState to disabled
 				if err := o.OperState.Event("disable"); err != nil {
@@ -282,18 +277,19 @@
 				for _, s := range o.Services {
 					s.Disable()
 				}
-				o.onuAlarmsInfoLock.Lock()
-				o.onuAlarmsInfo = make(map[omcilib.OnuAlarmInfoMapKey]omcilib.OnuAlarmInfo) //Basically reset everything on onu disable
-				o.onuAlarmsInfoLock.Unlock()
+
+			},
+			fmt.Sprintf("enter_%s", OnuStatePonDisabled): func(event *fsm.Event) {
+				o.cleanupOnuState()
 			},
 			// BBR states
-			"enter_eapol_flow_sent": func(e *fsm.Event) {
+			fmt.Sprintf("enter_%s", BbrOnuStateEapolFlowSent): func(e *fsm.Event) {
 				msg := bbsim.Message{
 					Type: bbsim.SendEapolFlow,
 				}
 				o.Channel <- msg
 			},
-			"enter_dhcp_flow_sent": func(e *fsm.Event) {
+			fmt.Sprintf("enter_%s", BbrOnuStateDhcpFlowSent): func(e *fsm.Event) {
 				msg := bbsim.Message{
 					Type: bbsim.SendDhcpFlow,
 				}
@@ -313,6 +309,20 @@
 	}).Debugf("Changing ONU InternalState from %s to %s", src, dst)
 }
 
+// cleanupOnuState this method is to clean the local state when the ONU is disabled
+func (o *Onu) cleanupOnuState() {
+	// clean the ONU state
+	o.PortNo = 0
+	o.Flows = []FlowKey{}
+	o.PonPort.removeOnuId(o.ID)
+	o.PonPort.removeAllocId(o.SerialNumber)
+	o.PonPort.removeGemPortBySn(o.SerialNumber)
+
+	o.onuAlarmsInfoLock.Lock()
+	o.onuAlarmsInfo = make(map[omcilib.OnuAlarmInfoMapKey]omcilib.OnuAlarmInfo) //Basically reset everything on onu disable
+	o.onuAlarmsInfoLock.Unlock()
+}
+
 // ProcessOnuMessages starts indication channel for each ONU
 func (o *Onu) ProcessOnuMessages(ctx context.Context, stream openolt.Openolt_EnableIndicationServer, client openolt.OpenoltClient) {
 	onuLogger.WithFields(log.Fields{
diff --git a/internal/bbsim/devices/onu_state_machine_test.go b/internal/bbsim/devices/onu_state_machine_test.go
index f0fd232..1de9eeb 100644
--- a/internal/bbsim/devices/onu_state_machine_test.go
+++ b/internal/bbsim/devices/onu_state_machine_test.go
@@ -17,6 +17,8 @@
 package devices
 
 import (
+	omcilib "github.com/opencord/bbsim/internal/common/omci"
+	me "github.com/opencord/omci-lib-go/generated"
 	"testing"
 
 	"gotest.tools/assert"
@@ -41,12 +43,24 @@
 		{ID: 1, Direction: "upstream"},
 		{ID: 2, Direction: "downstream"},
 	}
+	key := omcilib.OnuAlarmInfoMapKey{
+		MeInstance: 257,
+		MeClassID:  me.PhysicalPathTerminationPointEthernetUniClassID,
+	}
+	onu.onuAlarmsInfo[key] = omcilib.OnuAlarmInfo{SequenceNo: 1, AlarmBitMap: [28]byte{}}
+	onu.PonPort.storeOnuId(onu.ID, onu.SerialNumber)
+	onu.PonPort.storeAllocId(1, onu.SerialNumber)
+	onu.PonPort.storeGemPort(1, onu.SerialNumber)
 
 	_ = onu.InternalState.Event(OnuTxDisable)
 	assert.Equal(t, onu.InternalState.Current(), OnuStateDisabled)
 
 	assert.Equal(t, onu.PortNo, uint32(0))
+	assert.Equal(t, len(onu.onuAlarmsInfo), 0)
 	assert.Equal(t, len(onu.Flows), 0)
+	assert.Equal(t, len(onu.PonPort.AllocatedOnuIds), 0)
+	assert.Equal(t, len(onu.PonPort.AllocatedAllocIds), 0)
+	assert.Equal(t, len(onu.PonPort.AllocatedGemPorts), 0)
 }
 
 // check that I can go to auth_started only if
diff --git a/internal/bbsim/devices/pon.go b/internal/bbsim/devices/pon.go
index 3d74eb1..e351d00 100644
--- a/internal/bbsim/devices/pon.go
+++ b/internal/bbsim/devices/pon.go
@@ -26,6 +26,10 @@
 	log "github.com/sirupsen/logrus"
 )
 
+var ponLogger = log.WithFields(log.Fields{
+	"module": "PON",
+})
+
 type PonPort struct {
 	// BBSIM Internals
 	ID            uint32
@@ -72,7 +76,7 @@
 		},
 		fsm.Callbacks{
 			"enter_enabled": func(e *fsm.Event) {
-				oltLogger.WithFields(log.Fields{
+				ponLogger.WithFields(log.Fields{
 					"ID": ponPort.ID,
 				}).Debugf("Changing PON Port InternalState from %s to %s", e.Src, e.Dst)
 
@@ -80,11 +84,11 @@
 					if olt.ControlledActivation == Default || olt.ControlledActivation == OnlyPON {
 						for _, onu := range ponPort.Onus {
 							if err := onu.InternalState.Event(OnuTxInitialize); err != nil {
-								log.Errorf("Error initializing ONU: %v", err)
+								ponLogger.Errorf("Error initializing ONU: %v", err)
 								continue
 							}
 							if err := onu.InternalState.Event(OnuTxDiscover); err != nil {
-								log.Errorf("Error discover ONU: %v", err)
+								ponLogger.Errorf("Error discover ONU: %v", err)
 							}
 						}
 					}
@@ -93,7 +97,7 @@
 						// if ONUs are manually activated then only initialize them
 						for _, onu := range ponPort.Onus {
 							if err := onu.InternalState.Event(OnuTxInitialize); err != nil {
-								log.WithFields(log.Fields{
+								ponLogger.WithFields(log.Fields{
 									"Err":    err,
 									"OnuSn":  onu.Sn(),
 									"IntfId": onu.PonPortID,
@@ -104,8 +108,8 @@
 					} else {
 						for _, onu := range ponPort.Onus {
 							if onu.InternalState.Current() == OnuStatePonDisabled {
-								if err := onu.InternalState.Event(OnuStateEnabled); err != nil {
-									log.WithFields(log.Fields{
+								if err := onu.InternalState.Event(OnuTxEnable); err != nil {
+									ponLogger.WithFields(log.Fields{
 										"Err":    err,
 										"OnuSn":  onu.Sn(),
 										"IntfId": onu.PonPortID,
@@ -113,7 +117,7 @@
 								}
 							} else if onu.InternalState.Current() == OnuStateDisabled {
 								if err := onu.InternalState.Event(OnuTxInitialize); err != nil {
-									log.WithFields(log.Fields{
+									ponLogger.WithFields(log.Fields{
 										"Err":    err,
 										"OnuSn":  onu.Sn(),
 										"IntfId": onu.PonPortID,
@@ -121,7 +125,7 @@
 									continue
 								}
 								if err := onu.InternalState.Event(OnuTxDiscover); err != nil {
-									log.WithFields(log.Fields{
+									ponLogger.WithFields(log.Fields{
 										"Err":    err,
 										"OnuSn":  onu.Sn(),
 										"IntfId": onu.PonPortID,
@@ -129,7 +133,7 @@
 								}
 							} else if onu.InternalState.Current() == OnuStateInitialized {
 								if err := onu.InternalState.Event(OnuTxDiscover); err != nil {
-									log.WithFields(log.Fields{
+									ponLogger.WithFields(log.Fields{
 										"Err":    err,
 										"OnuSn":  onu.Sn(),
 										"IntfId": onu.PonPortID,
@@ -137,7 +141,7 @@
 								}
 							} else {
 								// this is to loudly report unexpected states in order to address them
-								log.WithFields(log.Fields{
+								ponLogger.WithFields(log.Fields{
 									"OnuSn":         onu.Sn(),
 									"IntfId":        onu.PonPortID,
 									"InternalState": onu.InternalState.Current(),
@@ -153,7 +157,7 @@
 						continue
 					}
 					if err := onu.InternalState.Event(OnuTxPonDisable); err != nil {
-						oltLogger.Errorf("Failed to move ONU in %s states: %v", OnuStatePonDisabled, err)
+						ponLogger.Errorf("Failed to move ONU in %s states: %v", OnuStatePonDisabled, err)
 					}
 				}
 			},
@@ -168,13 +172,13 @@
 		},
 		fsm.Callbacks{
 			"enter_up": func(e *fsm.Event) {
-				oltLogger.WithFields(log.Fields{
+				ponLogger.WithFields(log.Fields{
 					"ID": ponPort.ID,
 				}).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
 				olt.sendPonIndication(ponPort.ID)
 			},
 			"enter_down": func(e *fsm.Event) {
-				oltLogger.WithFields(log.Fields{
+				ponLogger.WithFields(log.Fields{
 					"ID": ponPort.ID,
 				}).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
 				olt.sendPonIndication(ponPort.ID)