SEBA-927 implemenation of controlled PON and ONU activation
updated controlledActivation to enum

Change-Id: Ie505c491755d3890a2ea4a86a9c74f17a5eab484
diff --git a/internal/bbsim/devices/pon.go b/internal/bbsim/devices/pon.go
index 24b541b..130c74f 100644
--- a/internal/bbsim/devices/pon.go
+++ b/internal/bbsim/devices/pon.go
@@ -31,17 +31,18 @@
 	ID     uint32
 	NumOnu int
 	Onus   []*Onu
-	Olt    OltDevice
+	Olt    *OltDevice
 
 	// PON Attributes
 	OperState *fsm.FSM
 	Type      string
 
 	// NOTE do we need a state machine for the PON Ports?
+	InternalState *fsm.FSM
 }
 
 // CreatePonPort creates pon port object
-func CreatePonPort(olt OltDevice, id uint32) *PonPort {
+func CreatePonPort(olt *OltDevice, id uint32) *PonPort {
 
 	ponPort := PonPort{
 		NumOnu: olt.NumOnuPerPon,
@@ -51,6 +52,61 @@
 		Onus:   []*Onu{},
 	}
 
+	ponPort.InternalState = fsm.NewFSM(
+		"created",
+		fsm.Events{
+			{Name: "enable", Src: []string{"created", "disabled"}, Dst: "enabled"},
+			{Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
+		},
+		fsm.Callbacks{
+			"enter_enabled": func(e *fsm.Event) {
+				oltLogger.WithFields(log.Fields{
+					"ID": ponPort.ID,
+				}).Debugf("Changing PON Port InternalState from %s to %s", e.Src, e.Dst)
+
+				if e.Src == "created" {
+					if olt.ControlledActivation == Default || olt.ControlledActivation == OnlyPON {
+						for _, onu := range ponPort.Onus {
+							if err := onu.InternalState.Event("initialize"); err != nil {
+								log.Errorf("Error initializing ONU: %v", err)
+								continue
+							}
+							if err := onu.InternalState.Event("discover"); err != nil {
+								log.Errorf("Error discover ONU: %v", err)
+							}
+						}
+					}
+				} else if e.Src == "disabled" {
+					for _, onu := range ponPort.Onus {
+						if onu.InternalState.Current() == "pon_disabled" {
+							if err := onu.InternalState.Event("discover"); err != nil {
+								log.Errorf("Error discover ONU: %v", err)
+							}
+						} else if onu.InternalState.Current() == "disabled" {
+							if err := onu.InternalState.Event("initialize"); err != nil {
+								log.Errorf("Error initialize ONU: %v", err)
+								continue
+							}
+							if err := onu.InternalState.Event("discover"); err != nil {
+								log.Errorf("Error discover ONU: %v", err)
+							}
+						}
+					}
+				}
+			},
+			"enter_disabled": func(e *fsm.Event) {
+				for _, onu := range ponPort.Onus {
+					if onu.InternalState.Current() == "initialized" {
+						continue
+					}
+					if err := onu.InternalState.Event("pon_disabled"); err != nil {
+						oltLogger.Errorf("Failed to move ONU in pon_disabled states: %v", err)
+					}
+				}
+			},
+		},
+	)
+
 	ponPort.OperState = fsm.NewFSM(
 		"down",
 		fsm.Events{
@@ -62,17 +118,13 @@
 				oltLogger.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{
 					"ID": ponPort.ID,
 				}).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
-
-				for _, onu := range ponPort.Onus {
-					if err := onu.InternalState.Event("pon_disabled"); err != nil {
-						oltLogger.Errorf("Failed to move ONU in pon_disabled states: %v", err)
-					}
-				}
+				olt.sendPonIndication(ponPort.ID)
 			},
 		},
 	)