SEBA-927 implemenation of controlled PON and ONU activation
updated controlledActivation to enum
Change-Id: I63ba732338f3df79f01a30703d9e6118d95bf8aa
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 016f148..f68ee9e 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -47,17 +47,17 @@
sync.Mutex
// BBSIM Internals
- ID int
- SerialNumber string
- NumNni int
- NumPon int
- NumOnuPerPon int
- InternalState *fsm.FSM
- channel chan Message
- nniPktInChannel chan *bbsim.PacketMsg // packets coming in from the NNI and going to VOLTHA
- nniHandle *pcap.Handle // handle on the NNI interface, close it when shutting down the NNI channel
-
- Delay int
+ ID int
+ SerialNumber string
+ NumNni int
+ NumPon int
+ NumOnuPerPon int
+ InternalState *fsm.FSM
+ channel chan Message
+ nniPktInChannel chan *bbsim.PacketMsg // packets coming in from the NNI and going to VOLTHA
+ nniHandle *pcap.Handle // handle on the NNI interface, close it when shutting down the NNI channel
+ Delay int
+ ControlledActivation mode
Pons []*PonPort
Nnis []*NniPort
@@ -78,7 +78,7 @@
return &olt
}
-func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, auth bool, dhcp bool, delay int, isMock bool) *OltDevice {
+func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, auth bool, dhcp bool, delay int, ca string, isMock bool) *OltDevice {
oltLogger.WithFields(log.Fields{
"ID": oltId,
"NumNni": nni,
@@ -100,6 +100,13 @@
Delay: delay,
}
+ if val, ok := ControlledActivationModes[ca]; ok {
+ olt.ControlledActivation = val
+ } else {
+ oltLogger.Warn("Unknown ControlledActivation Mode given, running in Default mode")
+ olt.ControlledActivation = Default
+ }
+
// OLT State machine
// NOTE do we need 2 state machines for the OLT? (InternalState and OperState)
olt.InternalState = fsm.NewFSM(
@@ -132,7 +139,7 @@
// create PON ports
availableCTag := cTagInit
for i := 0; i < pon; i++ {
- p := CreatePonPort(olt, uint32(i))
+ p := CreatePonPort(&olt, uint32(i))
// create ONU devices
for j := 0; j < onuPerPon; j++ {
@@ -209,22 +216,33 @@
// TODO handle hard poweroff (i.e. no indications sent to Voltha) vs soft poweroff
time.Sleep(1 * time.Second) // we need to give the OLT the time to respond to all the pending gRPC request before stopping the server
if err := o.StopOltServer(); err != nil {
+ oltLogger.Errorf("Error in stopping OLT server")
return err
}
+ for _, pon := range olt.Pons {
+ msg := Message{
+ Type: PonIndication,
+ Data: PonIndicationMessage{
+ OperState: DOWN,
+ PonPortID: pon.ID,
+ },
+ }
+ o.channel <- msg
+
+ for _, onu := range pon.Onus {
+ if onu.InternalState.Current() != "initialized" {
+ onu.InternalState.Event("disable")
+ }
+ }
+ }
+
// terminate the OLT's processOltMessages go routine
close(o.channel)
// terminate the OLT's processNniPacketIns go routine
go o.nniHandle.Close()
close(o.nniPktInChannel)
- for i := range olt.Pons {
- for _, onu := range olt.Pons[i].Onus {
- // NOTE while the olt is off, restore the ONU to the initial state
- onu.InternalState.SetState("created")
- }
- }
-
time.Sleep(time.Duration(rebootDelay) * time.Second)
if err := o.InternalState.Event("initialize"); err != nil {
@@ -277,6 +295,7 @@
// Enable implements the OpenOLT EnableIndicationServer functionality
func (o *OltDevice) Enable(stream openolt.Openolt_EnableIndicationServer) error {
oltLogger.Debug("Enable OLT called")
+ rebootFlag := false
// If enabled has already been called then an enabled context has
// been created. If this is the case then we want to cancel all the
@@ -285,6 +304,7 @@
o.Lock()
if o.enableContext != nil && o.enableContextCancel != nil {
o.enableContextCancel()
+ rebootFlag = true
}
o.enableContext, o.enableContextCancel = context.WithCancel(context.TODO())
o.Unlock()
@@ -321,25 +341,35 @@
go o.processOmciMessages(o.enableContext, stream, &wg)
- // send PON Port indications
- for i, pon := range o.Pons {
- msg := Message{
- Type: PonIndication,
- Data: PonIndicationMessage{
- OperState: UP,
- PonPortID: pon.ID,
- },
- }
- o.channel <- msg
-
- for _, onu := range o.Pons[i].Onus {
- if err := onu.InternalState.Event("initialize"); err != nil {
- log.Errorf("Error initializing ONU: %v", err)
- continue
+ if rebootFlag == true {
+ for _, pon := range o.Pons {
+ if pon.InternalState.Current() == "disabled" {
+ msg := Message{
+ Type: PonIndication,
+ Data: PonIndicationMessage{
+ OperState: UP,
+ PonPortID: pon.ID,
+ },
+ }
+ o.channel <- msg
}
- if err := onu.InternalState.Event("discover"); err != nil {
- log.Errorf("Error discover ONU: %v", err)
- return err
+ }
+ } else {
+
+ // 1. controlledActivation == Default: Send both PON and ONUs indications
+ // 2. controlledActivation == only-onu: that means only ONUs will be controlled activated, so auto send PON indications
+
+ if o.ControlledActivation == Default || o.ControlledActivation == OnlyONU {
+ // send PON Port indications
+ for _, pon := range o.Pons {
+ msg := Message{
+ Type: PonIndication,
+ Data: PonIndicationMessage{
+ OperState: UP,
+ PonPortID: pon.ID,
+ },
+ }
+ o.channel <- msg
}
}
}
@@ -468,25 +498,11 @@
}).Debug("Sent Indication_IntfOperInd for NNI")
}
-func (o *OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
- pon, _ := o.GetPonById(msg.PonPortID)
- if msg.OperState == UP {
- if err := pon.OperState.Event("enable"); err != nil {
- log.WithFields(log.Fields{
- "Type": pon.Type,
- "IntfId": pon.ID,
- "OperState": pon.OperState.Current(),
- }).Errorf("Can't move PON Port to enable state: %v", err)
- }
- } else if msg.OperState == DOWN {
- if err := pon.OperState.Event("disable"); err != nil {
- log.WithFields(log.Fields{
- "Type": pon.Type,
- "IntfId": pon.ID,
- "OperState": pon.OperState.Current(),
- }).Errorf("Can't move PON Port to disable state: %v", err)
- }
- }
+func (o *OltDevice) sendPonIndication(ponPortID uint32) {
+
+ stream := *o.OpenoltStream
+ pon, _ := o.GetPonById(ponPortID)
+ // Send IntfIndication for PON port
discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
IntfId: pon.ID,
OperState: pon.OperState.Current(),
@@ -502,6 +518,7 @@
"OperState": pon.OperState.Current(),
}).Debug("Sent Indication_IntfInd")
+ // Send IntfOperIndication for PON port
operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Type: pon.Type,
IntfId: pon.ID,
@@ -561,7 +578,14 @@
o.sendNniIndication(msg, stream)
case PonIndication:
msg, _ := message.Data.(PonIndicationMessage)
- o.sendPonIndication(msg, stream)
+ pon, _ := o.GetPonById(msg.PonPortID)
+ if msg.OperState == UP {
+ pon.OperState.Event("enable")
+ pon.InternalState.Event("enable")
+ } else if msg.OperState == DOWN {
+ pon.OperState.Event("disable")
+ pon.InternalState.Event("disable")
+ }
default:
oltLogger.Warnf("Received unknown message data %v for type %v in OLT Channel", message.Data, message.Type)
}
@@ -645,26 +669,6 @@
}).Warn("Stopped handling NNI Channel")
}
-func (o *OltDevice) handleReenableOlt() {
- // enable OLT
- oltMsg := Message{
- Type: OltIndication,
- Data: OltIndicationMessage{
- OperState: UP,
- },
- }
- o.channel <- oltMsg
-
- for i := range olt.Pons {
- for _, onu := range olt.Pons[i].Onus {
- if err := onu.InternalState.Event("discover"); err != nil {
- log.Errorf("Error discover ONU: %v", err)
- }
- }
- }
-
-}
-
// returns an ONU with a given Serial Number
func (o OltDevice) FindOnuBySn(serialNumber string) (*Onu, error) {
// TODO this function can be a performance bottleneck when we have many ONUs,
@@ -788,16 +792,17 @@
}).Info("Disabling OLT")
for _, pon := range o.Pons {
- // disable PONs
- msg := Message{
- Type: PonIndication,
- Data: PonIndicationMessage{
- OperState: DOWN,
- PonPortID: pon.ID,
- },
+ if pon.InternalState.Current() == "enabled" {
+ // disable PONs
+ msg := Message{
+ Type: PonIndication,
+ Data: PonIndicationMessage{
+ OperState: DOWN,
+ PonPortID: pon.ID,
+ },
+ }
+ o.channel <- msg
}
-
- o.channel <- msg
}
// Note that we are not disabling the NNI as the real OLT does not.
@@ -825,8 +830,18 @@
return nil
}
-func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
- oltLogger.Error("EnablePonIf not implemented")
+func (o OltDevice) EnablePonIf(_ context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
+ oltLogger.Errorf("EnablePonIf request received for PON %d", intf.IntfId)
+ ponID := intf.GetIntfId()
+ msg := Message{
+ Type: PonIndication,
+ Data: PonIndicationMessage{
+ OperState: UP,
+ PonPortID: ponID,
+ },
+ }
+ o.channel <- msg
+
return new(openolt.Empty), nil
}
@@ -995,20 +1010,27 @@
"oltId": o.ID,
}).Info("Received ReenableOlt request from VOLTHA")
- for _, pon := range o.Pons {
- msg := Message{
- Type: PonIndication,
- Data: PonIndicationMessage{
- OperState: UP,
- PonPortID: pon.ID,
- },
- }
- o.channel <- msg
+ // enable OLT
+ oltMsg := Message{
+ Type: OltIndication,
+ Data: OltIndicationMessage{
+ OperState: UP,
+ },
}
+ o.channel <- oltMsg
- // Openolt adapter will start processing indications only after success reponse of ReenableOlt
- // thats why need to send OLT and ONU indications after return of this function
- go o.handleReenableOlt()
+ for _, pon := range o.Pons {
+ if pon.InternalState.Current() == "disabled" {
+ msg := Message{
+ Type: PonIndication,
+ Data: PonIndicationMessage{
+ OperState: UP,
+ PonPortID: pon.ID,
+ },
+ }
+ o.channel <- msg
+ }
+ }
return new(openolt.Empty), nil
}