SEBA-958 send periodic port stats
Change-Id: I981e6c70b214845d87e8ae96b370fcdf58ccfef3
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 4aafaba..0209b88 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -63,6 +63,7 @@
ControlledActivation mode
EventChannel chan common.Event
PublishEvents bool
+ PortStatsInterval int
Pons []*PonPort
Nnis []*NniPort
@@ -84,32 +85,33 @@
return &olt
}
-func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, auth bool, dhcp bool, delay int, ca string, enablePerf bool, event bool, isMock bool) *OltDevice {
+func CreateOLT(options common.BBSimYamlConfig, isMock bool) *OltDevice {
oltLogger.WithFields(log.Fields{
- "ID": oltId,
- "NumNni": nni,
- "NumPon": pon,
- "NumOnuPerPon": onuPerPon,
+ "ID": options.Olt.ID,
+ "NumNni": options.Olt.NniPorts,
+ "NumPon": options.Olt.PonPorts,
+ "NumOnuPerPon": options.Olt.OnusPonPort,
}).Debug("CreateOLT")
olt = OltDevice{
- ID: oltId,
- SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", oltId),
+ ID: options.Olt.ID,
+ SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", options.Olt.ID),
OperState: getOperStateFSM(func(e *fsm.Event) {
oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
}),
- NumNni: nni,
- NumPon: pon,
- NumOnuPerPon: onuPerPon,
- Pons: []*PonPort{},
- Nnis: []*NniPort{},
- Delay: delay,
- Flows: make(map[FlowKey]openolt.Flow),
- enablePerf: enablePerf,
- PublishEvents: event,
+ NumNni: int(options.Olt.NniPorts),
+ NumPon: int(options.Olt.PonPorts),
+ NumOnuPerPon: int(options.Olt.OnusPonPort),
+ Pons: []*PonPort{},
+ Nnis: []*NniPort{},
+ Delay: options.BBSim.Delay,
+ Flows: make(map[FlowKey]openolt.Flow),
+ enablePerf: options.BBSim.EnablePerf,
+ PublishEvents: options.BBSim.Events,
+ PortStatsInterval: options.Olt.PortStatsInterval,
}
- if val, ok := ControlledActivationModes[ca]; ok {
+ if val, ok := ControlledActivationModes[options.BBSim.ControlledActivation]; ok {
olt.ControlledActivation = val
} else {
oltLogger.Warn("Unknown ControlledActivation Mode given, running in Default mode")
@@ -146,14 +148,14 @@
}
// create PON ports
- availableCTag := cTagInit
- for i := 0; i < pon; i++ {
+ availableCTag := options.BBSim.CTagInit
+ for i := 0; i < olt.NumPon; i++ {
p := CreatePonPort(&olt, uint32(i))
// create ONU devices
- for j := 0; j < onuPerPon; j++ {
+ for j := 0; j < olt.NumOnuPerPon; j++ {
delay := time.Duration(olt.Delay*j) * time.Millisecond
- o := CreateONU(&olt, *p, uint32(j+1), sTag, availableCTag, auth, dhcp, 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
}
@@ -391,6 +393,12 @@
}
oltLogger.Debug("Enable OLT Done")
+
+ if !o.enablePerf {
+ // Start a go routine to send periodic port stats to openolt adapter
+ go o.periodicPortStats(o.enableContext)
+ }
+
wg.Wait()
return nil
}
@@ -432,6 +440,39 @@
wg.Done()
}
+func (o *OltDevice) periodicPortStats(ctx context.Context) {
+ var portStats *openolt.PortStatistics
+ for {
+ select {
+ case <-time.After(time.Duration(o.PortStatsInterval) * time.Second):
+ // send NNI port stats
+ for _, port := range o.Nnis {
+ incrementStat := true
+ if port.OperState.Current() == "down" {
+ incrementStat = false
+ }
+ portStats, port.PacketCount = getPortStats(port.PacketCount, incrementStat)
+ o.sendPortStatsIndication(portStats, port.ID, port.Type)
+ }
+
+ // send PON port stats
+ for _, port := range o.Pons {
+ incrementStat := true
+ // do not increment port stats if PON port is down or no ONU is activated on PON port
+ if port.OperState.Current() == "down" || port.GetNumOfActiveOnus() < 1 {
+ incrementStat = false
+ }
+ portStats, port.PacketCount = getPortStats(port.PacketCount, incrementStat)
+ o.sendPortStatsIndication(portStats, port.ID, port.Type)
+ }
+ case <-ctx.Done():
+ log.Debug("Stop sending port stats")
+ return
+ }
+
+ }
+}
+
// Helpers method
func (o OltDevice) GetPonById(id uint32) (*PonPort, error) {
@@ -553,6 +594,22 @@
}).Debug("Sent Indication_IntfOperInd for PON")
}
+func (o *OltDevice) sendPortStatsIndication(stats *openolt.PortStatistics, portID uint32, portType string) {
+ oltLogger.WithFields(log.Fields{
+ "Type": portType,
+ "IntfId": portID,
+ }).Trace("Sending port stats")
+ stats.IntfId = InterfaceIDToPortNo(portID, portType)
+ data := &openolt.Indication_PortStats{
+ PortStats: stats,
+ }
+ stream := *o.OpenoltStream
+ if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+ oltLogger.Errorf("Failed to send PortStats: %v", err)
+ return
+ }
+}
+
// processOltMessages handles messages received over the OpenOLT interface
func (o *OltDevice) processOltMessages(ctx context.Context, stream openolt.Openolt_EnableIndicationServer, wg *sync.WaitGroup) {
oltLogger.Debug("Starting OLT Indication Channel")