[VOL-2687] Fixing state transition for ONU Shutdown/PowerOn
Change-Id: I23c38351371bef091919c0beb48132f8d59a08dc
diff --git a/internal/bbsim/api/onus_handler.go b/internal/bbsim/api/onus_handler.go
index 975b426..0f898e8 100644
--- a/internal/bbsim/api/onus_handler.go
+++ b/internal/bbsim/api/onus_handler.go
@@ -19,8 +19,8 @@
import (
"context"
"fmt"
-
"github.com/opencord/bbsim/api/bbsim"
+ "github.com/opencord/bbsim/internal/bbsim/alarmsim"
"github.com/opencord/bbsim/internal/bbsim/devices"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
@@ -97,16 +97,41 @@
return res, err
}
- dyingGasp := devices.Message{
- Type: devices.DyingGaspIndication,
- Data: devices.DyingGaspIndicationMessage{
- OnuID: onu.ID,
- PonPortID: onu.PonPortID,
- Status: "on", // TODO do we need a type for Dying Gasp Indication?
- },
+ dyingGasp := bbsim.ONUAlarmRequest{
+ AlarmType: "DyingGasp",
+ SerialNumber: onu.Sn(),
+ Status: "on",
}
- onu.Channel <- dyingGasp
+ if err := alarmsim.SimulateOnuAlarm(context.TODO(), &dyingGasp, olt); err != nil {
+ logger.WithFields(log.Fields{
+ "OnuId": onu.ID,
+ "IntfId": onu.PonPortID,
+ "OnuSn": onu.Sn(),
+ }).Errorf("Cannot send Dying Gasp: %s", err.Error())
+ res.StatusCode = int32(codes.FailedPrecondition)
+ res.Message = err.Error()
+ return res, err
+ }
+
+ losReq := bbsim.ONUAlarmRequest{
+ AlarmType: "LossOfSignal",
+ SerialNumber: onu.Sn(),
+ Status: "on",
+ }
+
+ if err := alarmsim.SimulateOnuAlarm(context.TODO(), &losReq, olt); err != nil {
+ logger.WithFields(log.Fields{
+ "OnuId": onu.ID,
+ "IntfId": onu.PonPortID,
+ "OnuSn": onu.Sn(),
+ }).Errorf("Cannot send LOS: %s", err.Error())
+ res.StatusCode = int32(codes.FailedPrecondition)
+ res.Message = err.Error()
+ return res, err
+ }
+
+ // TODO if it's the last ONU on the PON, then send a PON LOS
if err := onu.InternalState.Event("disable"); err != nil {
logger.WithFields(log.Fields{
@@ -155,7 +180,7 @@
return res, err
}
- if onu.InternalState.Current() == "created" {
+ if onu.InternalState.Current() == "created" || onu.InternalState.Current() == "disabled" {
if err := onu.InternalState.Event("initialize"); err != nil {
logger.WithFields(log.Fields{
"OnuId": onu.ID,
@@ -168,6 +193,23 @@
}
}
+ losReq := bbsim.ONUAlarmRequest{
+ AlarmType: "LossOfSignal",
+ SerialNumber: onu.Sn(),
+ Status: "off",
+ }
+
+ if err := alarmsim.SimulateOnuAlarm(context.TODO(), &losReq, olt); err != nil {
+ logger.WithFields(log.Fields{
+ "OnuId": onu.ID,
+ "IntfId": onu.PonPortID,
+ "OnuSn": onu.Sn(),
+ }).Errorf("Cannot send LOS: %s", err.Error())
+ res.StatusCode = int32(codes.FailedPrecondition)
+ res.Message = err.Error()
+ return res, err
+ }
+
if err := onu.InternalState.Event("discover"); err != nil {
logger.WithFields(log.Fields{
"OnuId": onu.ID,
@@ -179,6 +221,17 @@
return res, err
}
+ if err := onu.InternalState.Event("enable"); err != nil {
+ logger.WithFields(log.Fields{
+ "OnuId": onu.ID,
+ "IntfId": onu.PonPortID,
+ "OnuSn": onu.Sn(),
+ }).Errorf("Cannot enable ONU: %s", err.Error())
+ res.StatusCode = int32(codes.FailedPrecondition)
+ res.Message = err.Error()
+ return res, err
+ }
+
res.StatusCode = int32(codes.OK)
res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
diff --git a/internal/bbsim/devices/messageTypes.go b/internal/bbsim/devices/messageTypes.go
index 4872af0..8bb1d25 100644
--- a/internal/bbsim/devices/messageTypes.go
+++ b/internal/bbsim/devices/messageTypes.go
@@ -25,30 +25,29 @@
type MessageType int
const (
- OltIndication MessageType = 0
- NniIndication MessageType = 1
- PonIndication MessageType = 2
- OnuDiscIndication MessageType = 3
- OnuIndication MessageType = 4
- OMCI MessageType = 5
- FlowUpdate MessageType = 6
- StartEAPOL MessageType = 7
- StartDHCP MessageType = 8
- OnuPacketOut MessageType = 9
- DyingGaspIndication MessageType = 10
+ OltIndication MessageType = 0
+ NniIndication MessageType = 1
+ PonIndication MessageType = 2
+ OnuDiscIndication MessageType = 3
+ OnuIndication MessageType = 4
+ OMCI MessageType = 5
+ FlowUpdate MessageType = 6
+ StartEAPOL MessageType = 7
+ StartDHCP MessageType = 8
+ OnuPacketOut MessageType = 9
// BBR messages
- OmciIndication MessageType = 11 // this are OMCI messages going from the OLT to VOLTHA
- SendEapolFlow MessageType = 12
- SendDhcpFlow MessageType = 13
- OnuPacketIn MessageType = 14
+ OmciIndication MessageType = 10 // this are OMCI messages going from the OLT to VOLTHA
+ SendEapolFlow MessageType = 11
+ SendDhcpFlow MessageType = 12
+ OnuPacketIn MessageType = 13
//IGMP
- IGMPMembershipReportV2 MessageType = 15 // Version 2 Membership Report (JOIN)
- IGMPLeaveGroup MessageType = 16 // Leave Group
+ IGMPMembershipReportV2 MessageType = 14 // Version 2 Membership Report (JOIN)
+ IGMPLeaveGroup MessageType = 15 // Leave Group
- AlarmIndication MessageType = 17 // message data is an openolt.AlarmIndication
- IGMPMembershipReportV3 MessageType = 18 // Version 3 Membership Report
+ AlarmIndication MessageType = 16 // message data is an openolt.AlarmIndication
+ IGMPMembershipReportV3 MessageType = 17 // Version 3 Membership Report
)
func (m MessageType) String() string {
@@ -63,7 +62,6 @@
"StartEAPOL",
"StartDHCP",
"OnuPacketOut",
- "DyingGaspIndication",
"OmciIndication",
"SendEapolFlow",
"SendDhcpFlow",
@@ -136,12 +134,6 @@
Type packetHandlers.PacketType
}
-type DyingGaspIndicationMessage struct {
- PonPortID uint32
- OnuID uint32
- Status string
-}
-
type OperState int
const (
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index fa0ba5d..8a0d01e 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -98,14 +98,14 @@
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,
+ NumNni: nni,
+ NumPon: pon,
+ NumOnuPerPon: onuPerPon,
+ Pons: []*PonPort{},
+ Nnis: []*NniPort{},
+ Delay: delay,
+ Flows: make(map[FlowKey]openolt.Flow),
+ enablePerf: enablePerf,
PublishEvents: event,
}
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index ee16cb8..43759c9 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -126,7 +126,7 @@
// DEVICE Lifecycle
{Name: "initialize", Src: []string{"created", "disabled"}, Dst: "initialized"},
{Name: "discover", Src: []string{"initialized", "pon_disabled"}, Dst: "discovered"},
- {Name: "enable", Src: []string{"discovered", "disabled"}, Dst: "enabled"},
+ {Name: "enable", Src: []string{"discovered"}, Dst: "enabled"},
{Name: "receive_eapol_flow", Src: []string{"enabled", "gem_port_added"}, Dst: "eapol_flow_received"},
{Name: "add_gem_port", Src: []string{"enabled", "eapol_flow_received"}, Dst: "gem_port_added"},
// NOTE should disabled state be different for oper_disabled (emulating an error) and admin_disabled (received a disabled call via VOLTHA)?
@@ -163,6 +163,15 @@
"enter_initialized": func(e *fsm.Event) {
// create new channel for ProcessOnuMessages Go routine
o.Channel = make(chan Message, 2048)
+
+ if err := o.OperState.Event("enable"); err != nil {
+ onuLogger.WithFields(log.Fields{
+ "OnuId": o.ID,
+ "IntfId": o.PonPortID,
+ "OnuSn": o.Sn(),
+ }).Errorf("Cannot change ONU OperState to up: %s", err.Error())
+ }
+
if !isMock {
// start ProcessOnuMessages Go routine
go o.ProcessOnuMessages(olt.enableContext, *olt.OpenoltStream, nil)
@@ -190,6 +199,13 @@
o.Channel <- msg
},
"enter_disabled": func(event *fsm.Event) {
+ if err := o.OperState.Event("disable"); err != nil {
+ onuLogger.WithFields(log.Fields{
+ "OnuId": o.ID,
+ "IntfId": o.PonPortID,
+ "OnuSn": o.Sn(),
+ }).Errorf("Cannot change ONU OperState to down: %s", err.Error())
+ }
msg := Message{
Type: OnuIndication,
Data: OnuIndicationMessage{
@@ -378,9 +394,6 @@
} else if msg.Type == packetHandlers.DHCP {
dhcp.HandleNextBbrPacket(o.ID, o.PonPortID, o.Sn(), o.STag, o.HwAddress, o.DoneChannel, msg.Packet, client)
}
- case DyingGaspIndication:
- msg, _ := message.Data.(DyingGaspIndicationMessage)
- o.sendDyingGaspInd(msg, stream)
case OmciIndication:
msg, _ := message.Data.(OmciIndicationMessage)
o.handleOmci(msg, client)
@@ -481,31 +494,6 @@
return sn
}
-// NOTE handle_/process methods can change the ONU internal state as they are receiving messages
-// send method should not change the ONU state
-
-func (o *Onu) sendDyingGaspInd(msg DyingGaspIndicationMessage, stream openolt.Openolt_EnableIndicationServer) error {
- alarmData := &openolt.AlarmIndication_DyingGaspInd{
- DyingGaspInd: &openolt.DyingGaspIndication{
- IntfId: msg.PonPortID,
- OnuId: msg.OnuID,
- Status: "on",
- },
- }
- data := &openolt.Indication_AlarmInd{AlarmInd: &openolt.AlarmIndication{Data: alarmData}}
-
- if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
- onuLogger.Errorf("Failed to send DyingGaspInd : %v", err)
- return err
- }
- onuLogger.WithFields(log.Fields{
- "IntfId": msg.PonPortID,
- "OnuSn": o.Sn(),
- "OnuId": msg.OnuID,
- }).Info("sendDyingGaspInd")
- return nil
-}
-
func (o *Onu) sendOnuDiscIndication(msg OnuDiscIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
discoverData := &openolt.Indication_OnuDiscInd{OnuDiscInd: &openolt.OnuDiscIndication{
IntfId: msg.Onu.PonPortID,
@@ -547,7 +535,7 @@
SerialNumber: o.SerialNumber,
}}
if err := stream.Send(&openolt.Indication{Data: indData}); err != nil {
- // TODO do we need to transition to a broken state?
+ // NOTE do we need to transition to a broken state?
log.Errorf("Failed to send Indication_OnuInd: %v", err)
}
onuLogger.WithFields(log.Fields{
@@ -652,20 +640,20 @@
func (o *Onu) handleFlowUpdate(msg OnuFlowUpdateMessage) {
onuLogger.WithFields(log.Fields{
- "DstPort": msg.Flow.Classifier.DstPort,
- "EthType": fmt.Sprintf("%x", msg.Flow.Classifier.EthType),
- "FlowId": msg.Flow.FlowId,
- "FlowType": msg.Flow.FlowType,
- "GemportId": msg.Flow.GemportId,
- "InnerVlan": msg.Flow.Classifier.IVid,
- "IntfId": msg.Flow.AccessIntfId,
- "IpProto": msg.Flow.Classifier.IpProto,
- "OnuId": msg.Flow.OnuId,
- "OnuSn": o.Sn(),
- "OuterVlan": msg.Flow.Classifier.OVid,
- "PortNo": msg.Flow.PortNo,
- "SrcPort": msg.Flow.Classifier.SrcPort,
- "UniID": msg.Flow.UniId,
+ "DstPort": msg.Flow.Classifier.DstPort,
+ "EthType": fmt.Sprintf("%x", msg.Flow.Classifier.EthType),
+ "FlowId": msg.Flow.FlowId,
+ "FlowType": msg.Flow.FlowType,
+ "GemportId": msg.Flow.GemportId,
+ "InnerVlan": msg.Flow.Classifier.IVid,
+ "IntfId": msg.Flow.AccessIntfId,
+ "IpProto": msg.Flow.Classifier.IpProto,
+ "OnuId": msg.Flow.OnuId,
+ "OnuSn": o.Sn(),
+ "OuterVlan": msg.Flow.Classifier.OVid,
+ "PortNo": msg.Flow.PortNo,
+ "SrcPort": msg.Flow.Classifier.SrcPort,
+ "UniID": msg.Flow.UniId,
"ClassifierOPbits": msg.Flow.Classifier.OPbits,
}).Debug("ONU receives Flow")