SEBA-758 send periodic port stats to voltha
SEBA-790 get flow, gemport, and tcont information through API
fix lint errors
Change-Id: I10909e1992eba71d8e54c976ccbcea8778e35539
diff --git a/Makefile b/Makefile
index 37ae4a0..6cfcc89 100644
--- a/Makefile
+++ b/Makefile
@@ -29,6 +29,7 @@
DOCKER_LABEL_BUILD_DATE ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ")
GRPC_GW_PATH ?= $(shell GO111MODULE=on go list -f '{{ .Dir }}' -m github.com/grpc-ecosystem/grpc-gateway)
+PROTO_PATH ?= $(shell GO111MODULE=on go list -f '{{ .Dir }}' -m github.com/opencord/voltha-protos)
bbsim: dep bbsimapi
GO111MODULE=on go build -i -v -o $@
@@ -45,6 +46,7 @@
@protoc -I ./api \
-I${GRPC_GW_PATH}/third_party/googleapis/ \
-I${GRPC_GW_PATH}/ \
+ -I${PROTO_PATH}/protos/ \
--go_out=plugins=grpc:api/ \
--grpc-gateway_out=logtostderr=true,allow_delete_body=true:api/ \
api/bbsim.proto
@@ -54,7 +56,7 @@
-I${GRPC_GW_PATH}/third_party/googleapis/ \
-I${GRPC_GW_PATH}/ \
--swagger_out=logtostderr=true,allow_delete_body=true:api/swagger/ \
- bbsim.proto
+ api/bbsim.proto
test: dep bbsimapi
GO111MODULE=on go test -v ./...
diff --git a/api/bbsim.proto b/api/bbsim.proto
index 494f947..1b35541 100644
--- a/api/bbsim.proto
+++ b/api/bbsim.proto
@@ -17,35 +17,40 @@
import "google/api/annotations.proto";
import "protoc-gen-swagger/options/annotations.proto";
+import "voltha_protos/openolt.proto";
+import "voltha_protos/tech_profile.proto";
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
- info: {
+ info: {
title: "BBSim API";
version: "1.0";
- };
- schemes: HTTP;
- consumes: "application/json";
- produces: "application/json";
- responses: {
+ contact: {
+ url: "http://opencord.org";
+ };
+ };
+ schemes: HTTP;
+ consumes: "application/json";
+ produces: "application/json";
+ responses: {
key: "404";
value: {
- description: "Returned when the resource does not exist.";
- schema: {
- json_schema: {
- type: STRING;
+ description: "Returned when the resource does not exist.";
+ schema: {
+ json_schema: {
+ type: STRING;
}
- }
+ }
}
- }
+ }
};
// OLT information
message OLTInfo {
- int64 olt_id = 1;
- string olt_serial = 2;
- string olt_ip = 3;
- string olt_state = 4;
- string olt_vendor = 5;
+ int64 olt_id = 1;
+ string olt_serial = 2;
+ string olt_ip = 3;
+ string olt_state = 4;
+ string olt_vendor = 5;
}
// ONU information
@@ -58,139 +63,159 @@
string oper_state = 4;
// ONU internal state
string onu_state = 5;
+ repeated uint32 gemports = 6;
+ Tconts tconts = 7;
}
// Bulk ONU operations
message ONUs {
- repeated ONUInfo onus = 1;
+ repeated ONUInfo onus = 1;
}
message ONURequest {
- ONUInfo onu = 1;
- ONUs onus_batch = 2;
+ ONUInfo onu = 1;
+ ONUs onus_batch = 2;
}
// Port information
message PortInfo {
- string port_type = 1;
- uint32 port_id = 2;
- int32 pon_port_max_onus = 3;
- uint32 pon_port_active_onus = 4;
- string port_state = 5;
- string alarm_state = 6;
+ string port_type = 1;
+ uint32 port_id = 2;
+ uint32 pon_port_max_onus = 3;
+ uint32 pon_port_active_onus = 4;
+ string port_state = 5;
+ string alarm_state = 6;
}
// Bulk port information
message Ports {
- repeated PortInfo ports = 1;
+ repeated PortInfo ports = 1;
}
// BBSim status
message OLTStatusResponse {
- OLTInfo olt = 1;
- repeated PortInfo ports = 2;
+ OLTInfo olt = 1;
+ repeated PortInfo ports = 2;
}
// BBSim response message
message BBSimResponse {
- string status_msg = 1;
+ string status_msg = 1;
}
// ONU alarm request
message ONUAlarmRequest {
- // ONU serial number
- string onu_serial = 1;
- // Alarm types are:
- // "signaldegrade"
- // "lossofomcichannel"
- // "lossofploam"
- string alarm_type = 2;
- // "on"/"off" indicates raised or cleared alarm
- string status = 3; }
+ // ONU serial number
+ string onu_serial = 1;
+ // Alarm types are:
+ // "signaldegrade"
+ // "lossofomcichannel"
+ // "lossofploam"
+ string alarm_type = 2;
+ // "on"/"off" indicates raised or cleared alarm
+ string status = 3; }
// OLT alarm request
message OLTAlarmRequest {
- uint32 port_id = 1;
- string port_type = 2;
- string status = 3;
+ uint32 port_id = 1;
+ string port_type = 2;
+ string status = 3;
}
// Device action
message DeviceAction {
- string device_type = 1; // ONU or OLT
- string device_serial_number = 2; // Device serial number
- string device_action = 3; // soft or hard reboot
+ string device_type = 1; // ONU or OLT
+ string serial_number = 2; // Device serial number
+ string action = 3; // soft or hard reboot
+}
+
+message Tconts {
+ fixed32 uni_id = 4;
+ fixed32 port_no = 5;
+ repeated tech_profile.TrafficScheduler tconts = 3;
+}
+
+message Flows {
+ repeated openolt.Flow flows = 1;
}
message Empty {}
service BBSimService {
- // Get current status of OLT
- rpc OLTStatus(Empty) returns (OLTStatusResponse) {
- option (google.api.http) = {
- get : "/v1/olt"
- additional_bindings {get : "/v1/olt/status"}
- };
- }
+ // Get current status of OLT
+ rpc OLTStatus(Empty) returns (OLTStatusResponse) {
+ option (google.api.http) = {
+ get : "/v1/olt"
+ additional_bindings {get : "/v1/olt/status"}
+ };
+ }
- // Get status of a PON/NNI port
- rpc PortStatus(PortInfo) returns (Ports) {
- option (google.api.http) = {
- get : "/v1/olt/ports/{port_type}"
- };
- }
+ // Get status of a PON/NNI port
+ rpc PortStatus(PortInfo) returns (Ports) {
+ option (google.api.http) = {
+ get : "/v1/olt/ports/{port_type}/{port_id}/status"
+ };
+ }
- // Get status of all or specific ONUs
- rpc ONUStatus(ONURequest) returns (ONUs) {
- option (google.api.http) = {
- get : "/v1/olt/onus"
- additional_bindings { get : "/v1/olt/ports/{onu.pon_port_id}/onus" }
- additional_bindings { get : "/v1/olt/onus/{onu.onu_serial}" }
- };
- }
+ // Get status of all or specific ONUs
+ rpc ONUStatus(ONURequest) returns (ONUs) {
+ option (google.api.http) = {
+ get : "/v1/olt/onus"
+ additional_bindings { get : "/v1/olt/ports/{onu.pon_port_id}/onus" }
+ additional_bindings { get : "/v1/olt/onus/{onu.onu_serial}" }
+ };
+ }
- // Single/bulk activate ONU(s) for specific PON port(s)
- rpc ONUActivate(ONURequest) returns (BBSimResponse) {
- option (google.api.http) = {
- post : "/v1/olt/onus"
- body: "onus_batch"
- additional_bindings { post : "/v1/olt/ports/{onu.pon_port_id}/onus" }
- additional_bindings { post : "/v1/olt/ports/{onu.pon_port_id}/onus/{onu.onu_serial}" }
- };
- }
-
- // Deactivate ONU(s) for specific PON port(s) specified by
- // a given onu_serial, onu_id, or pon_port_id
- rpc ONUDeactivate(ONURequest) returns (BBSimResponse) {
- option (google.api.http) = {
- delete : "/v1/olt/onus"
- body: "onus_batch"
- additional_bindings { delete: "/v1/olt/onus/{onu.onu_serial}" }
- additional_bindings { delete: "/v1/olt/ports/{onu.pon_port_id}/onus" }
- additional_bindings { delete: "/v1/olt/ports/{onu.pon_port_id}/onus/{onu.onu_id}" }
- };
- }
+ // Single/bulk activate ONU(s) for specific PON port(s)
+ rpc ONUActivate(ONURequest) returns (BBSimResponse) {
+ option (google.api.http) = {
+ post : "/v1/olt/onus"
+ body: "onus_batch"
+ additional_bindings { post : "/v1/olt/ports/{onu.pon_port_id}/onus" }
+ additional_bindings { post : "/v1/olt/ports/{onu.pon_port_id}/onus/{onu.onu_serial}" }
+ };
+ }
- // Generate ONU related alarms
- rpc GenerateONUAlarm(ONUAlarmRequest) returns (BBSimResponse) {
- option (google.api.http) = {
- post : "/v1/olt/onus/{onu_serial}/alarms/{alarm_type}/{status}"
- };
- }
+ // Deactivate ONU(s) for specific PON port(s) specified by
+ // a given onu_serial, onu_id, or pon_port_id
+ rpc ONUDeactivate(ONURequest) returns (BBSimResponse) {
+ option (google.api.http) = {
+ delete : "/v1/olt/onus"
+ body: "onus_batch"
+ additional_bindings { delete: "/v1/olt/onus/{onu.onu_serial}" }
+ additional_bindings { delete: "/v1/olt/ports/{onu.pon_port_id}/onus" }
+ additional_bindings { delete: "/v1/olt/ports/{onu.pon_port_id}/onus/{onu.onu_id}" }
+ };
+ }
- // Generate OLT related alarms
- rpc GenerateOLTAlarm(OLTAlarmRequest) returns (BBSimResponse) {
- option (google.api.http) = {
- post : "/v1/olt/ports/{port_type}/{port_id}/alarms/los/{status}"
- };
- }
+ // Generate ONU related alarms
+ rpc GenerateONUAlarm(ONUAlarmRequest) returns (BBSimResponse) {
+ option (google.api.http) = {
+ post : "/v1/olt/onus/{onu_serial}/alarms/{alarm_type}/{status}"
+ };
+ }
- // Perform actions on OLT/ONU devices (e.g. reboot)
- rpc PerformDeviceAction(DeviceAction) returns (BBSimResponse) {
- option (google.api.http) = {
- patch: "/v1/{device_type}/reboot"
- additional_bindings { patch : "/v1/olt/{device_type}/{device_serial_number}/reboot/{device_action}"}
- };
- }
+ // Generate OLT related alarms
+ rpc GenerateOLTAlarm(OLTAlarmRequest) returns (BBSimResponse) {
+ option (google.api.http) = {
+ post : "/v1/olt/ports/{port_type}/{port_id}/alarms/los/{status}"
+ };
+ }
+
+ // Perform actions on OLT/ONU devices (e.g. reboot)
+ rpc PerformDeviceAction(DeviceAction) returns (BBSimResponse) {
+ option (google.api.http) = {
+ patch: "/v1/{device_type}/action/{action}"
+ additional_bindings { patch : "/v1/olt/{device_type}/{serial_number}/action/{action}"}
+ };
+ }
+
+ // Get flows
+ rpc GetFlows(ONUInfo) returns(Flows) {
+ option (google.api.http) = {
+ get: "/v1/olt/flows"
+ additional_bindings {get: "/v1/olt/onu/{onu_serial}/flows"}
+ };
+ }
}
diff --git a/common/logger/logger.go b/common/logger/logger.go
index 6efe0f1..3701284 100644
--- a/common/logger/logger.go
+++ b/common/logger/logger.go
@@ -31,6 +31,22 @@
func Setup(kafkaBroker string, level string) {
logger := log.New()
+ formatter := &log.TextFormatter{
+ ForceColors: false,
+ DisableColors: false,
+ EnvironmentOverrideColors: false,
+ DisableTimestamp: false,
+ FullTimestamp: true,
+ TimestampFormat: time.RFC3339Nano,
+ DisableSorting: false,
+ SortingFunc: nil,
+ DisableLevelTruncation: false,
+ QuoteEmptyFields: true,
+ FieldMap: nil,
+ CallerPrettyfier: nil,
+ }
+ logger.SetFormatter(formatter)
+
//logger.SetReportCaller(true)
myLogger = logger.WithField("topics", []string{"bbsim.log"})
@@ -121,3 +137,8 @@
func Debug(msg string, args ...interface{}) {
myLogger.Debugf(msg, args...)
}
+
+// Trace logs with log level trace
+func Trace(msg string, args ...interface{}) {
+ myLogger.Tracef(msg, args...)
+}
diff --git a/core/alarms.go b/core/alarms.go
index 2261b55..c48c493 100644
--- a/core/alarms.go
+++ b/core/alarms.go
@@ -19,9 +19,10 @@
import (
"strconv"
- pb "github.com/opencord/voltha-bbsim/api"
+ api "github.com/opencord/voltha-bbsim/api"
"github.com/opencord/voltha-bbsim/common/logger"
"github.com/opencord/voltha-bbsim/device"
+ flowHandler "github.com/opencord/voltha-bbsim/flow"
openolt "github.com/opencord/voltha-protos/go/openolt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -40,49 +41,49 @@
AlarmOff = "off"
)
-func (s *Server) handleOnuAlarm(in *pb.ONUAlarmRequest) (*pb.BBSimResponse, error) {
+func (s *Server) handleOnuAlarm(in *api.ONUAlarmRequest) (*api.BBSimResponse, error) {
+ logger.Trace("handleOnuAlarm() invoked")
value, ok := s.SNmap.Load(in.OnuSerial)
- onu := value.(*device.Onu)
if !ok {
- return &pb.BBSimResponse{}, status.Errorf(codes.NotFound, "no active or discovered onu found with serial number "+in.OnuSerial)
+ return &api.BBSimResponse{}, status.Errorf(codes.NotFound, "no active or discovered onu found with serial number "+in.OnuSerial)
}
- if (onu.InternalState == device.ONU_LOS_RAISED || onu.InternalState == device.ONU_LOS_ON_OLT_PON_LOS) &&
+ onu := value.(*device.Onu)
+ if (onu.InternalState == device.OnuLosRaised || onu.InternalState == device.OnuLosOnOltPonLos) &&
(in.AlarmType != OnuLossOfPloam) {
- return &pb.BBSimResponse{}, status.Errorf(codes.Aborted, in.OnuSerial+" is not reachable, can not send onu alarm")
+ return &api.BBSimResponse{}, status.Errorf(codes.Aborted, in.OnuSerial+" is not reachable, can not send onu alarm")
}
if s.Olt.PonIntfs[onu.IntfID].AlarmState == device.PonLosRaised && (in.AlarmType != OnuLossOfPloam) {
// Don't send onu alarm as OLT-PON is down
- return &pb.BBSimResponse{}, status.Errorf(codes.Aborted, "pon-port down, can not send onu alarm")
+ return &api.BBSimResponse{}, status.Errorf(codes.Aborted, "pon-port down, can not send onu alarm")
}
switch in.AlarmType {
case OnuLossOfOmciChannel:
Ind := formulateLossOfOmciChannelAlarm(in.Status, onu)
if in.Status == AlarmOn {
- onu.UpdateIntState(device.ONU_OMCI_CHANNEL_LOS_RAISED)
+ onu.UpdateIntState(device.OnuOmciChannelLosRaised)
} else {
- onu.UpdateIntState(device.ONU_ACTIVE)
+ onu.UpdateIntState(device.OnuActive)
}
s.alarmCh <- Ind
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
case OnuSignalDegrade:
Ind := formulateSignalDegradeAlarm(in.Status, onu)
s.alarmCh <- Ind
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
case OnuLossOfPloam:
if in.Status == AlarmOn {
- onu.UpdateIntState(device.ONU_LOS_RAISED)
+ onu.UpdateIntState(device.OnuLosRaised)
device.UpdateOnusOpStatus(onu.IntfID, onu, "down")
} else {
- onu.UpdateIntState(device.ONU_ACTIVE)
+ onu.UpdateIntState(device.OnuActive)
device.UpdateOnusOpStatus(onu.IntfID, onu, "up")
- // TODO is it required to check onu state?
err := sendOnuDiscInd(*s.EnableServer, onu)
if err != nil {
- logger.Error("Error: %v", err.Error())
+ logger.Error("Error: %s", err.Error())
}
}
Ind := formulateLossOfPLOAM(in.Status, onu)
@@ -100,17 +101,18 @@
default:
logger.Debug("Unhandled alarm type")
- return &pb.BBSimResponse{}, status.Errorf(codes.Unimplemented, "Unhandled alarm type")
+ return &api.BBSimResponse{}, status.Errorf(codes.Unimplemented, "Unhandled alarm type")
}
}
-func (s *Server) handleOltAlarm(in *pb.OLTAlarmRequest) (*pb.BBSimResponse, error) {
+func (s *Server) handleOltAlarm(in *api.OLTAlarmRequest) (*api.BBSimResponse, error) {
+ logger.Trace("handleOltAlarm() invoked")
switch in.PortType {
case device.IntfNni:
if !s.isNniIntfPresentInOlt(in.PortId) {
- return &pb.BBSimResponse{}, status.Errorf(codes.NotFound, strconv.Itoa(int(in.PortId))+" NNI not present in olt")
+ return &api.BBSimResponse{}, status.Errorf(codes.NotFound, strconv.Itoa(int(in.PortId))+" NNI not present in olt")
}
Ind := formulateOLTLOSAlarm(in.Status, in.PortId, device.IntfNni)
@@ -119,13 +121,13 @@
case device.IntfPon:
if !s.isPonIntfPresentInOlt(in.PortId) {
- return &pb.BBSimResponse{}, status.Errorf(codes.NotFound, strconv.Itoa(int(in.PortId))+" PON not present in olt")
+ return &api.BBSimResponse{}, status.Errorf(codes.NotFound, strconv.Itoa(int(in.PortId))+" PON not present in olt")
}
Ind := formulateOLTLOSAlarm(in.Status, in.PortId, in.PortType)
s.alarmCh <- Ind
onusOperstat := s.setPONPortState(in.PortId, in.Status)
for _, onu := range s.Onumap[in.PortId] {
- if onu.InternalState == device.ONU_LOS_RAISED || onu.InternalState == device.ONU_FREE {
+ if onu.InternalState == device.OnuLosRaised || onu.InternalState == device.OnuFree {
continue // Skip for onus which have independently raised onu los
}
@@ -136,23 +138,33 @@
s.sendOnuLosOnOltPonLos(onu, in.Status)
}
default:
- return &pb.BBSimResponse{}, status.Errorf(codes.Internal, "invalid interface type provided")
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid interface type provided")
}
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
}
func (s *Server) setNNIPortState(portID uint32, alarmstatus string) {
+ logger.Trace("setNNIPortState() invoked")
switch alarmstatus {
case AlarmOn:
s.Olt.UpdateNniPortState(portID, device.NniLosRaised, "down")
+ err := flowHandler.PortDown(0)
+ if err != nil {
+ logger.Error("Failed in port down %v", err)
+ }
case AlarmOff:
s.Olt.UpdateNniPortState(portID, device.NniLosCleared, "up")
+ err := flowHandler.PortUp(0)
+ if err != nil {
+ logger.Error("Failed in port up %v", err)
+ }
}
}
func (s *Server) setPONPortState(portID uint32, alarmstatus string) string {
+ logger.Trace("setPONPortState() invoked")
switch alarmstatus {
case AlarmOn:
s.Olt.UpdatePonPortState(portID, device.PonLosRaised, "down")
@@ -166,12 +178,13 @@
}
func (s *Server) sendOnuLosOnOltPonLos(onu *device.Onu, status string) {
- var internalState device.DeviceState
+ logger.Trace("sendOnuLosOnOltPonLos() invoked")
+ var internalState device.State
if status == AlarmOn {
- internalState = device.ONU_LOS_ON_OLT_PON_LOS
+ internalState = device.OnuLosOnOltPonLos
} else if status == AlarmOff {
- internalState = device.ONU_ACTIVE
+ internalState = device.OnuActive
}
Ind := formulateLossOfPLOAM(status, onu)
@@ -189,7 +202,7 @@
}
func formulateLossOfOmciChannelAlarm(status string, onu *device.Onu) *openolt.Indication {
- logger.Debug("formulateLossofOmciChannelAlarm() invoked")
+ logger.Trace("formulateLossofOmciChannelAlarm() invoked")
alarmIndication := &openolt.AlarmIndication_OnuLossOmciInd{
OnuLossOmciInd: &openolt.OnuLossOfOmciChannelIndication{
@@ -209,7 +222,7 @@
}
func formulateSignalDegradeAlarm(status string, onu *device.Onu) *openolt.Indication {
- logger.Debug("formulateSignalDegrade() invoked")
+ logger.Trace("formulateSignalDegrade() invoked")
alarmIndication := &openolt.AlarmIndication_OnuSignalDegradeInd{
OnuSignalDegradeInd: &openolt.OnuSignalDegradeIndication{
IntfId: onu.IntfID,
@@ -227,7 +240,7 @@
}
func formulateLossOfPLOAM(status string, onu *device.Onu) *openolt.Indication {
- logger.Debug("formulateLossOfPLOAM() invoked")
+ logger.Trace("formulateLossOfPLOAM() invoked")
alarmIndication := &openolt.AlarmIndication_OnuAlarmInd{OnuAlarmInd: &openolt.OnuAlarmIndication{
IntfId: onu.IntfID,
@@ -258,12 +271,17 @@
return Ind
}
-func (s *Server) checkAndSendOltPonLos(serial string, status string, intfType string) (*pb.BBSimResponse, error) {
- value, _ := s.SNmap.Load(serial)
+func (s *Server) checkAndSendOltPonLos(serial string, status string, intfType string) (*api.BBSimResponse, error) {
+ value, ok := s.SNmap.Load(serial)
+ if !ok {
+ logger.Debug(serial + " not found in OLT-" + strconv.Itoa(int(s.Olt.ID)))
+ return &api.BBSimResponse{}, nil
+ }
+
onu := value.(*device.Onu)
if s.getNoOfActiveOnuByPortID(onu.IntfID) == 0 {
logger.Warn("Warning: Sending OLT-LOS, as all onus on pon-port %v raised los", onu.IntfID)
- request := &pb.OLTAlarmRequest{PortId: onu.IntfID, Status: AlarmOn, PortType: device.IntfPon}
+ request := &api.OLTAlarmRequest{PortId: onu.IntfID, Status: AlarmOn, PortType: device.IntfPon}
resp, err := s.handleOltAlarm(request)
return resp, err
}
@@ -273,11 +291,12 @@
s.alarmCh <- Ind
}
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
}
func interfaceIDToPortNo(intfid uint32, intfType string) uint32 {
- // Converts interface-id to port-numbers that can be understood by the voltha
+ logger.Trace("interfaceIDToPortNo() invoked")
+ // Converts interface-id to port-numbers that can be understood by the VOLTHA
if intfType == device.IntfNni {
// nni at voltha starts with 65536
// nni = 65536 + interface_id
diff --git a/core/api_handler.go b/core/api_handler.go
index 8bc2c09..470f365 100644
--- a/core/api_handler.go
+++ b/core/api_handler.go
@@ -22,16 +22,26 @@
"strconv"
"time"
- pb "github.com/opencord/voltha-bbsim/api"
+ api "github.com/opencord/voltha-bbsim/api"
"github.com/opencord/voltha-bbsim/common/logger"
"github.com/opencord/voltha-bbsim/device"
+ "github.com/opencord/voltha-bbsim/flow"
+ openolt "github.com/opencord/voltha-protos/go/openolt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
-// handleONUActivate process ONU status request
-func (s *Server) handleONUStatusRequest(in *pb.ONUInfo) (*pb.ONUs, error) {
- onuInfo := &pb.ONUs{}
+// Constants for reboot delays
+const (
+ OltRebootDelay = 40
+ OnuSoftRebootDelay = 10
+ OnuHardRebootDelay = 30
+)
+
+// handleONUStatusRequest process ONU status request
+func (s *Server) handleONUStatusRequest(in *api.ONUInfo) (*api.ONUs, error) {
+ logger.Trace("handleONUStatusRequest() invoked")
+ onuInfo := &api.ONUs{}
if in.OnuSerial != "" { // Get status of single ONU by SerialNumber
// Get OpenOlt serial number from string
sn, err := getOpenoltSerialNumber(in.OnuSerial)
@@ -73,14 +83,14 @@
}
// handleONUActivate method handles ONU activate requests from user.
-func (s *Server) handleONUActivate(in []*pb.ONUInfo) (*pb.BBSimResponse, error) {
- logger.Info("handleONUActivate request received")
+func (s *Server) handleONUActivate(in []*api.ONUInfo) (*api.BBSimResponse, error) {
+ logger.Trace("handleONUActivate request received")
logger.Debug("Received values: %+v\n", in)
// Check if indication is enabled
if s.EnableServer == nil {
logger.Error(OLTNotEnabled)
- return &pb.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, OLTNotEnabled)
+ return &api.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, OLTNotEnabled)
}
onuaddmap := make(map[uint32][]*device.Onu)
@@ -90,12 +100,21 @@
for _, onu := range in {
intfid := onu.PonPortId
+ if !s.isPonIntfPresentInOlt(intfid) {
+ return &api.BBSimResponse{}, status.Errorf(codes.OutOfRange, "PON-"+strconv.Itoa(int(intfid))+
+ " not present in OLT-"+strconv.Itoa(int(s.Olt.ID)))
+ }
+
+ if s.Olt.PonIntfs[intfid].AlarmState == device.PonLosRaised {
+ return &api.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, "pon-"+strconv.Itoa(int(intfid))+" is not active")
+ }
+
// Get the free ONU object for the intfid
Onu, err := s.GetNextFreeOnu(intfid)
if err != nil {
markONUsFree(onuaddmap)
logger.Error("Failed to get free ONU object for intfID %d :%v", intfid, err)
- return &pb.BBSimResponse{}, status.Errorf(codes.ResourceExhausted, err.Error())
+ return &api.BBSimResponse{}, status.Errorf(codes.ResourceExhausted, err.Error())
}
// Check if Serial number is provided by user
@@ -104,9 +123,9 @@
sn, err := getOpenoltSerialNumber(onu.OnuSerial)
if err != nil {
logger.Error("Failed to get OpenOlt serial number %v", err)
- Onu.InternalState = device.ONU_FREE
+ Onu.InternalState = device.OnuFree
markONUsFree(onuaddmap)
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "serial number: "+onu.OnuSerial+" is invalid")
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "serial number: "+onu.OnuSerial+" is invalid")
}
// Check if serial number is not duplicate in requested ONUs
@@ -115,8 +134,8 @@
logger.Error("Duplicate serial number found %s", sn)
// Mark ONUs free
markONUsFree(onuaddmap)
- Onu.InternalState = device.ONU_FREE
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "duplicate serial number: "+onu.OnuSerial+" provided")
+ Onu.InternalState = device.OnuFree
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "duplicate serial number: "+onu.OnuSerial+" provided")
}
}
newSerialNums = append(newSerialNums, onu.OnuSerial)
@@ -127,8 +146,8 @@
logger.Error("Provided serial number %v already exist", sn)
// Mark ONUs free
markONUsFree(onuaddmap)
- Onu.InternalState = device.ONU_FREE
- return &pb.BBSimResponse{}, status.Errorf(codes.AlreadyExists, "serial number: "+onu.OnuSerial+" already exist")
+ Onu.InternalState = device.OnuFree
+ return &api.BBSimResponse{}, status.Errorf(codes.AlreadyExists, "serial number: "+onu.OnuSerial+" already exist")
}
// Store user provided serial number in ONU object
@@ -143,11 +162,12 @@
s.activateONUs(*s.EnableServer, onuaddmap)
}
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
}
// handleONUDeactivate deactivates ONU described by a single ONUInfo object
-func (s *Server) handleONUDeactivate(in *pb.ONUInfo) error {
+func (s *Server) handleONUDeactivate(in *api.ONUInfo) error {
+ logger.Trace("handleONUDeactivate() invoked")
if s.EnableServer == nil {
logger.Error(OLTNotEnabled)
@@ -191,15 +211,32 @@
}
func (s *Server) handleOLTReboot() {
- logger.Debug("HandleOLTReboot() invoked")
+ logger.Trace("HandleOLTReboot() invoked")
logger.Debug("Sending stop to serverActionCh")
s.serverActionCh <- OpenOltStop
- time.Sleep(40 * time.Second)
+
+ // Delete all flows
+ err := flow.DeleteAllFlows()
+ if err != nil {
+ logger.Warn("%v", err)
+ }
+
+ // clear flowMap
+ s.FlowMap = make(map[device.FlowKey]*openolt.Flow)
+
+ // clear flow IDs from ONU objects
+ for intfID := range s.Onumap {
+ for _, onu := range s.Onumap[intfID] {
+ onu.Flows = nil
+ }
+ }
+
+ time.Sleep(OltRebootDelay * time.Second)
logger.Debug("Sending start to serverActionCh")
s.serverActionCh <- OpenOltStart
for {
- if s.Olt.GetIntState() == device.OLT_ACTIVE {
+ if s.Olt.GetIntState() == device.OltActive {
logger.Info("Info: OLT reactivated")
break
}
@@ -209,23 +246,24 @@
}
func (s *Server) handleONUHardReboot(onu *device.Onu) {
- logger.Debug("handleONUHardReboot() invoked")
+ logger.Trace("handleONUHardReboot() invoked")
_ = sendDyingGaspInd(*s.EnableServer, onu.IntfID, onu.OnuID)
device.UpdateOnusOpStatus(onu.IntfID, onu, "down")
// send operstat down to voltha
_ = sendOnuInd(*s.EnableServer, onu, "down", "up")
// Give OEH some time to perform cleanup
- time.Sleep(30 * time.Second)
+ time.Sleep(OnuHardRebootDelay * time.Second)
s.activateOnu(onu)
}
func (s *Server) handleONUSoftReboot(IntfID uint32, OnuID uint32) {
- logger.Debug("handleONUSoftReboot() invoked")
+ logger.Trace("handleONUSoftReboot() invoked")
onu, err := s.GetOnuByID(OnuID, IntfID)
if err != nil {
logger.Error("No onu found with given OnuID on interface %v", IntfID)
+ return
}
- OnuAlarmRequest := &pb.ONUAlarmRequest{
+ OnuAlarmRequest := &api.ONUAlarmRequest{
OnuSerial: stringifySerialNumber(onu.SerialNumber),
AlarmType: OnuLossOfPloam,
Status: "on",
@@ -236,7 +274,7 @@
logger.Error(err.Error())
}
// Clear alarm
- time.Sleep(10 * time.Second)
+ time.Sleep(OnuSoftRebootDelay * time.Second)
OnuAlarmRequest.Status = "off"
_, err = s.handleOnuAlarm(OnuAlarmRequest)
if err != nil {
@@ -246,12 +284,13 @@
// GetNextFreeOnu returns free onu object for specified interface ID
func (s *Server) GetNextFreeOnu(intfid uint32) (*device.Onu, error) {
+ logger.Trace("GetNextFreeOnu() invoked")
onus, ok := s.Onumap[intfid]
if !ok {
return nil, errors.New("interface " + strconv.Itoa(int(intfid)) + " not present in ONU map")
}
for _, onu := range onus {
- if onu.InternalState == device.ONU_FREE {
+ if onu.InternalState == device.OnuFree {
// If auto generated serial number is already used by some other ONU,
// continue to find for other free object
snkey := stringifySerialNumber(onu.SerialNumber)
@@ -259,7 +298,7 @@
continue
}
// Update Onu Internal State
- onu.InternalState = device.ONU_INACTIVE
+ onu.InternalState = device.OnuInactive
return onu, nil
}
}
@@ -268,8 +307,9 @@
// DeactivateAllOnuByIntfID deletes all ONUs for given PON port ID
func (s *Server) DeactivateAllOnuByIntfID(intfid uint32) error {
+ logger.Trace("DeactivateAllOnuByIntfID() invoked")
for _, onu := range s.Onumap[intfid] {
- if onu.InternalState == device.ONU_FREE || onu.InternalState == device.ONU_INACTIVE {
+ if onu.InternalState == device.OnuFree || onu.InternalState == device.OnuInactive {
continue
}
if err := s.HandleOnuDeactivate(onu); err != nil {
@@ -281,10 +321,11 @@
// HandleOnuDeactivate method handles ONU state changes and sending Indication to voltha
func (s *Server) HandleOnuDeactivate(onu *device.Onu) error {
- logger.Debug("Deactivating ONU %d for Intf: %d", onu.OnuID, onu.IntfID)
+ logger.Trace("HandleOnuDeactivate() invoked")
+ logger.Info("Deactivating ONU %d for Intf: %d", onu.OnuID, onu.IntfID)
// Update ONU internal state to ONU_INACTIVE
- s.updateDevIntState(onu, device.ONU_INACTIVE)
+ s.updateDevIntState(onu, device.OnuInactive)
// Update ONU operstate to down
onu.OperState = "down"
@@ -296,80 +337,106 @@
}
func markONUsFree(onumap map[uint32][]*device.Onu) {
+ logger.Trace("markONUsFree() invoked")
for intfid := range onumap {
for _, onu := range onumap[intfid] {
- onu.UpdateIntState(device.ONU_FREE)
+ onu.UpdateIntState(device.OnuFree)
}
}
}
-func copyONUInfo(onu *device.Onu) *pb.ONUInfo {
- onuData := &pb.ONUInfo{
+func copyONUInfo(onu *device.Onu) *api.ONUInfo {
+ onuData := &api.ONUInfo{
OnuId: onu.OnuID,
PonPortId: onu.IntfID,
OnuSerial: stringifySerialNumber(onu.SerialNumber),
OnuState: device.ONUState[onu.InternalState],
OperState: onu.OperState,
}
+
+ // update gemports
+ for _, gemPorts := range onu.GemPortMap {
+ onuData.Gemports = append(onuData.Gemports, gemPorts...)
+ }
+
+ // fill T-CONT data for ONU
+ if onu.Tconts != nil {
+ onuData.Tconts = &api.Tconts{
+ UniId: onu.Tconts.UniId,
+ PortNo: onu.Tconts.PortNo,
+ Tconts: onu.Tconts.TrafficScheds,
+ }
+ }
+
return onuData
}
-func (s *Server) fetchPortDetail(intfID uint32, portType string) (*pb.PortInfo, error) {
- logger.Debug("fetchPortDetail() invoked")
- portInfo := &pb.PortInfo{}
- switch portType {
- case device.IntfNni:
- if !s.isNniIntfPresentInOlt(intfID) {
- return &pb.PortInfo{}, errors.New("NNI " + strconv.Itoa(int(intfID)) + " not present in " +
- strconv.Itoa(int(s.Olt.ID)))
- }
- portInfo = &pb.PortInfo{
- PortType: portType,
- PortId: intfID,
- PonPortMaxOnus: 0,
- PonPortActiveOnus: 0,
- PortState: s.Olt.NniIntfs[intfID].OperState,
- AlarmState: device.OLTAlarmStateToString[s.Olt.NniIntfs[intfID].AlarmState],
- }
- return portInfo, nil
+func (s *Server) fetchPortDetail(intfID uint32, portType string) (*api.PortInfo, error) {
+ logger.Trace("fetchPortDetail() invoked %s-%d", portType, intfID)
- case device.IntfPon:
- if !s.isPonIntfPresentInOlt(intfID) {
- return &pb.PortInfo{}, errors.New("PON " + strconv.Itoa(int(intfID)) + " not present in OLT-" +
- strconv.Itoa(int(s.Olt.ID)))
- }
- portInfo = &pb.PortInfo{
- PortType: portType,
- PortId: intfID,
- PonPortMaxOnus: int32(len(s.Onumap[uint32(intfID)])),
- PonPortActiveOnus: s.getNoOfActiveOnuByPortID(intfID),
- PortState: s.Olt.PonIntfs[intfID].OperState,
- AlarmState: device.OLTAlarmStateToString[s.Olt.PonIntfs[intfID].AlarmState],
- }
- return portInfo, nil
- default:
- return &pb.PortInfo{}, errors.New(portType + " is not a valid port type")
+ portInfo := &api.PortInfo{}
+ var maxOnu, activeOnu uint32
+ var alarmState device.AlarmState
+ var state string
+
+ // Get info for specified port
+ if portType == device.IntfNni && s.isNniIntfPresentInOlt(intfID) {
+ state = s.Olt.NniIntfs[intfID].OperState
+ alarmState = s.Olt.NniIntfs[intfID].AlarmState
+
+ } else if portType == device.IntfPon && s.isPonIntfPresentInOlt(intfID) {
+ maxOnu = uint32(len(s.Onumap[intfID]))
+ activeOnu = s.getNoOfActiveOnuByPortID(intfID)
+ state = s.Olt.PonIntfs[intfID].OperState
+ alarmState = s.Olt.PonIntfs[intfID].AlarmState
+
+ } else {
+ return &api.PortInfo{}, errors.New(portType + "-" + strconv.Itoa(int(intfID)) + " not present in OLT-" +
+ strconv.Itoa(int(s.Olt.ID)))
}
+
+ // fill proto structure
+ portInfo = &api.PortInfo{
+ PortType: portType,
+ PortId: intfID,
+ PonPortMaxOnus: maxOnu,
+ PonPortActiveOnus: activeOnu,
+ PortState: state,
+ }
+
+ // update alarm state only when alarm is raised
+ if alarmState == device.NniLosRaised || alarmState == device.PonLosRaised {
+ portInfo.AlarmState = device.OLTAlarmStateToString[alarmState]
+ }
+
+ return portInfo, nil
}
-func (s *Server) validateDeviceActionRequest(request *pb.DeviceAction) (*pb.DeviceAction, error) {
+func (s *Server) validateDeviceActionRequest(request *api.DeviceAction) (*api.DeviceAction, error) {
+ logger.Trace("validateDeviceActionRequest() invoked")
switch request.DeviceType {
case DeviceTypeOnu:
- if request.DeviceSerialNumber == "" {
+ if request.SerialNumber == "" {
return request, errors.New("onu serial number can not be blank")
}
- if len(request.DeviceSerialNumber) != SerialNumberLength {
+ if len(request.SerialNumber) != SerialNumberLength {
return request, errors.New("invalid serial number provided")
}
- if request.DeviceAction != SoftReboot && request.DeviceAction != HardReboot {
+ _, exist := s.SNmap.Load(request.SerialNumber)
+ if !exist {
+ return &api.DeviceAction{}, errors.New(request.SerialNumber + " not present in OLT-" +
+ strconv.Itoa(int(s.Olt.ID)))
+ }
+
+ if request.Action != SoftReboot && request.Action != HardReboot {
return request, errors.New("invalid device action provided")
}
return request, nil
case DeviceTypeOlt:
request.DeviceType = DeviceTypeOlt
- request.DeviceAction = HardReboot
+ request.Action = HardReboot
return request, nil
default:
return request, errors.New("invalid device type")
@@ -379,7 +446,7 @@
func (s *Server) getNoOfActiveOnuByPortID(portID uint32) uint32 {
var noOfActiveOnus uint32
for _, onu := range s.Onumap[portID] {
- if onu.InternalState == device.ONU_ACTIVE || onu.InternalState == device.ONU_OMCIACTIVE {
+ if onu.InternalState >= device.OnuActive {
noOfActiveOnus++
}
}
diff --git a/core/api_service.go b/core/api_service.go
index 7475484..f09b036 100644
--- a/core/api_service.go
+++ b/core/api_service.go
@@ -20,10 +20,9 @@
"context"
"net"
"net/http"
- "sync"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
- pb "github.com/opencord/voltha-bbsim/api"
+ api "github.com/opencord/voltha-bbsim/api"
"github.com/opencord/voltha-bbsim/common/logger"
"github.com/opencord/voltha-bbsim/device"
"google.golang.org/grpc"
@@ -43,10 +42,10 @@
)
// OLTStatus method returns OLT status.
-func (s *Server) OLTStatus(ctx context.Context, in *pb.Empty) (*pb.OLTStatusResponse, error) {
- logger.Debug("OLTStatus request received")
- oltInfo := &pb.OLTStatusResponse{
- Olt: &pb.OLTInfo{
+func (s *Server) OLTStatus(ctx context.Context, in *api.Empty) (*api.OLTStatusResponse, error) {
+ logger.Trace("OLTStatus request received")
+ oltInfo := &api.OLTStatusResponse{
+ Olt: &api.OLTInfo{
OltId: int64(s.Olt.ID),
OltSerial: s.Olt.SerialNumber,
OltIp: getOltIP().String(),
@@ -69,38 +68,32 @@
}
// PortStatus method returns Port status.
-func (s *Server) PortStatus(ctx context.Context, in *pb.PortInfo) (*pb.Ports, error) {
- portInfo := &pb.Ports{}
- logger.Debug("PortStatus() invoked")
- if in.PortType == device.IntfNni {
- for _, nniPort := range s.Olt.NniIntfs {
- nniPortInfo, _ := s.fetchPortDetail(nniPort.IntfID, nniPort.Type)
- portInfo.Ports = append(portInfo.Ports, nniPortInfo)
- }
- } else if in.PortType == device.IntfPon {
- for _, ponPort := range s.Olt.PonIntfs {
- ponPortInfo, _ := s.fetchPortDetail(ponPort.IntfID, ponPort.Type)
- portInfo.Ports = append(portInfo.Ports, ponPortInfo)
- }
- } else {
- return &pb.Ports{}, status.Errorf(codes.InvalidArgument, "Invalid port type")
+func (s *Server) PortStatus(ctx context.Context, in *api.PortInfo) (*api.Ports, error) {
+ logger.Trace("PortStatus() invoked")
+ ports := &api.Ports{}
+ portInfo, err := s.fetchPortDetail(in.PortId, in.PortType)
+ if err != nil {
+ return &api.Ports{}, status.Errorf(codes.InvalidArgument, err.Error())
}
- return portInfo, nil
+
+ ports.Ports = append(ports.Ports, portInfo)
+ return ports, nil
}
// ONUStatus method returns ONU status.
-func (s *Server) ONUStatus(ctx context.Context, in *pb.ONURequest) (*pb.ONUs, error) {
- logger.Debug("ONUStatus request received")
+func (s *Server) ONUStatus(ctx context.Context, in *api.ONURequest) (*api.ONUs, error) {
+ logger.Trace("ONUStatus request received")
if in.GetOnu() != nil {
logger.Debug("Received single ONU: %+v, %d\n", in.GetOnu(), in.GetOnu().PonPortId)
return s.handleONUStatusRequest(in.GetOnu())
}
- logger.Debug("Received bulk ONUs status request")
- onuInfo := &pb.ONUs{}
+
+ logger.Debug("Received all ONUS status request")
+ onuInfo := &api.ONUs{}
for intfid := range s.Onumap {
for _, onu := range s.Onumap[intfid] {
- if onu.InternalState != device.ONU_FREE {
+ if onu.InternalState != device.OnuFree {
onuInfo.Onus = append(onuInfo.Onus, copyONUInfo(onu))
}
}
@@ -109,11 +102,11 @@
}
// ONUActivate method handles ONU activate requests from user.
-func (s *Server) ONUActivate(ctx context.Context, in *pb.ONURequest) (*pb.BBSimResponse, error) {
- logger.Info("ONUActivate request received")
+func (s *Server) ONUActivate(ctx context.Context, in *api.ONURequest) (*api.BBSimResponse, error) {
+ logger.Trace("ONUActivate request received")
logger.Debug("Received values: %+v\n", in)
- var onuInfo = []*pb.ONUInfo{}
+ var onuInfo []*api.ONUInfo
// Activate single ONU
if in.GetOnu() != nil {
logger.Debug("Received single ONU: %+v\n", in.GetOnu())
@@ -123,14 +116,14 @@
onuInfo = in.GetOnusBatch().GetOnus()
} else {
logger.Debug("Received empty request body")
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, RequestFailed)
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, RequestFailed)
}
resp, err := s.handleONUActivate(onuInfo)
return resp, err
}
// ONUDeactivate method handles ONU deactivation request.
-func (s *Server) ONUDeactivate(ctx context.Context, in *pb.ONURequest) (*pb.BBSimResponse, error) {
+func (s *Server) ONUDeactivate(ctx context.Context, in *api.ONURequest) (*api.BBSimResponse, error) {
logger.Info("ONUDeactivate request received")
// deactivate single ONU
@@ -138,7 +131,7 @@
logger.Debug("Received single ONU: %+v\n", in.GetOnu())
err := s.handleONUDeactivate(in.GetOnu())
if err != nil {
- return &pb.BBSimResponse{}, status.Errorf(codes.Aborted, RequestFailed)
+ return &api.BBSimResponse{}, status.Errorf(codes.Aborted, RequestFailed)
}
} else if len(in.GetOnusBatch().GetOnus()) != 0 { // bulk deactivate
logger.Debug("Received multiple ONUs")
@@ -146,7 +139,7 @@
logger.Debug("ONU values: %+v\n", onuinfo)
err := s.handleONUDeactivate(onuinfo)
if err != nil {
- return &pb.BBSimResponse{}, status.Errorf(codes.Aborted, RequestFailed)
+ return &api.BBSimResponse{}, status.Errorf(codes.Aborted, RequestFailed)
}
}
} else {
@@ -154,62 +147,89 @@
for intfID := range s.Onumap {
if err := s.DeactivateAllOnuByIntfID(intfID); err != nil {
logger.Error("Failed in ONUDeactivate: %v", err)
- return &pb.BBSimResponse{}, status.Errorf(codes.Aborted, RequestFailed)
+ return &api.BBSimResponse{}, status.Errorf(codes.Aborted, RequestFailed)
}
}
}
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
+
}
// GenerateONUAlarm RPC generates alarm for the onu
-func (s *Server) GenerateONUAlarm(ctx context.Context, in *pb.ONUAlarmRequest) (*pb.BBSimResponse, error) {
- logger.Debug("GenerateONUAlarms() invoked")
+func (s *Server) GenerateONUAlarm(ctx context.Context, in *api.ONUAlarmRequest) (*api.BBSimResponse, error) {
+ logger.Trace("GenerateONUAlarms() invoked")
if in.OnuSerial == "" {
- return &pb.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, "serial number can not be blank")
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "serial number can not be blank")
}
if len(in.OnuSerial) != SerialNumberLength {
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid serial number given (length mismatch)")
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid serial number given (length mismatch)")
}
if in.Status != "on" && in.Status != "off" {
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid alarm status provided")
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid alarm status provided")
}
if s.alarmCh == nil {
- return &pb.BBSimResponse{}, status.Errorf(codes.Internal, "alarm-channel not created, can not send alarm")
+ return &api.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, "alarm-channel not created, can not send alarm")
}
- // TODO put these checks inside handleOnuAlarm for modularity
resp, err := s.handleOnuAlarm(in)
return resp, err
}
// GenerateOLTAlarm RPC generates alarm for the OLT
-func (s *Server) GenerateOLTAlarm(ctx context.Context, in *pb.OLTAlarmRequest) (*pb.BBSimResponse, error) {
- logger.Debug("GenerateOLTAlarm() invoked")
+func (s *Server) GenerateOLTAlarm(ctx context.Context, in *api.OLTAlarmRequest) (*api.BBSimResponse, error) {
+ logger.Trace("GenerateOLTAlarm() invoked")
if in.Status != "on" && in.Status != "off" {
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid alarm status provided")
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, "invalid alarm status provided")
}
if s.alarmCh == nil {
- return &pb.BBSimResponse{}, status.Errorf(codes.Internal, "alarm-channel not created, can not send alarm")
+ return &api.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, "alarm-channel not created, can not send alarm")
}
resp, err := s.handleOltAlarm(in)
if err != nil {
return resp, err
}
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
}
// PerformDeviceAction rpc take the device request and performs OLT and ONU hard and soft reboot
-func (s *Server) PerformDeviceAction(ctx context.Context, in *pb.DeviceAction) (*pb.BBSimResponse, error) {
- logger.Debug("PerformDeviceAction() invoked")
+func (s *Server) PerformDeviceAction(ctx context.Context, in *api.DeviceAction) (*api.BBSimResponse, error) {
+ logger.Trace("PerformDeviceAction() invoked")
if s.deviceActionCh == nil {
- return &pb.BBSimResponse{}, status.Errorf(codes.Internal, "device action channel not created, can not entertain request")
+ return &api.BBSimResponse{}, status.Errorf(codes.FailedPrecondition, "device action channel not created, can not entertain request")
}
in, err := s.validateDeviceActionRequest(in)
if err != nil {
- return &pb.BBSimResponse{}, status.Errorf(codes.InvalidArgument, err.Error())
+ return &api.BBSimResponse{}, status.Errorf(codes.InvalidArgument, err.Error())
}
s.deviceActionCh <- in
- return &pb.BBSimResponse{StatusMsg: RequestAccepted}, nil
+ return &api.BBSimResponse{StatusMsg: RequestAccepted}, nil
+}
+
+// GetFlows returns all flows or flows for specified ONU
+func (s *Server) GetFlows(ctx context.Context, in *api.ONUInfo) (*api.Flows, error) {
+ logger.Info("GetFlow request received")
+ flows := &api.Flows{}
+ if in.OnuSerial == "" {
+ for _, flow := range s.FlowMap {
+ flowInfo := flow
+ flows.Flows = append(flows.Flows, flowInfo)
+ }
+ } else {
+ serialNumber, err := getOpenoltSerialNumber(in.OnuSerial)
+ if err != nil {
+ return flows, status.Errorf(codes.InvalidArgument, err.Error())
+ }
+ onu, found := s.getOnuFromSNmap(serialNumber)
+ if !found {
+ return flows, status.Errorf(codes.InvalidArgument, "ONU with serial number %s not activated yet", in.OnuSerial)
+ }
+ for _, flowKey := range onu.Flows {
+ flow := s.FlowMap[flowKey]
+ flowInfo := flow
+ flows.Flows = append(flows.Flows, flowInfo)
+ }
+ }
+ return flows, nil
}
// NewMgmtAPIServer method starts BBSim gRPC server.
@@ -221,7 +241,7 @@
}
// StartRestGatewayService method starts REST server for BBSim.
-func StartRestGatewayService(grpcAddress string, hostandport string, wg *sync.WaitGroup) {
+func StartRestGatewayService(grpcAddress string, hostandport string) {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
@@ -229,7 +249,7 @@
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
// Register REST endpoints
- err := pb.RegisterBBSimServiceHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
+ err := api.RegisterBBSimServiceHandlerFromEndpoint(ctx, mux, grpcAddress, opts)
if err != nil {
logger.Error("%v", err)
return
diff --git a/core/core_server.go b/core/core_server.go
index a8d9d52..64bd6c7 100644
--- a/core/core_server.go
+++ b/core/core_server.go
@@ -29,7 +29,7 @@
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
omci "github.com/opencord/omci-sim"
- pb "github.com/opencord/voltha-bbsim/api"
+ api "github.com/opencord/voltha-bbsim/api"
"github.com/opencord/voltha-bbsim/common/logger"
"github.com/opencord/voltha-bbsim/device"
flowHandler "github.com/opencord/voltha-bbsim/flow"
@@ -49,6 +49,7 @@
SerialNumberLength = 12
OpenOltStart = "start"
OpenOltStop = "stop"
+ AutoDiscoveryDelay = 5
)
// Server structure consists of all the params required for BBsim.
@@ -78,9 +79,9 @@
eapolOut chan *byteMsg
dhcpIn chan *byteMsg
dhcpOut chan *byteMsg
- FlowMap map[FlowKey]*openolt.Flow
+ FlowMap map[device.FlowKey]*openolt.Flow
alarmCh chan *openolt.Indication
- deviceActionCh chan *pb.DeviceAction
+ deviceActionCh chan *api.DeviceAction
serverActionCh chan string
}
@@ -91,26 +92,19 @@
}
type byteMsg struct {
- IntfId uint32
- OnuId uint32
+ IntfID uint32
+ OnuID uint32
Byte []byte
}
type stateReport struct {
device device.Device
- current device.DeviceState
- next device.DeviceState
+ current device.State
+ next device.State
}
-// FlowKey used for FlowMap key
-type FlowKey struct {
- FlowID uint32
- FlowDirection string
-}
-
-//Has options (OLT id, number onu ports) from mediator
// NewCore initialize OLT and ONU objects
-func NewCore(opt *option) *Server {
+func NewCore(opt *Option) *Server {
// TODO: make it decent
oltid := opt.oltid
npon := opt.npon
@@ -145,17 +139,14 @@
eapolOut: make(chan *byteMsg, 1024),
dhcpIn: make(chan *byteMsg, 1024),
dhcpOut: make(chan *byteMsg, 1024),
- FlowMap: make(map[FlowKey]*openolt.Flow),
+ FlowMap: make(map[device.FlowKey]*openolt.Flow),
serverActionCh: make(chan string),
}
logger.Info("OLT %d created: %v", s.Olt.ID, s.Olt)
-
- nnni := s.Olt.NumNniIntf
- logger.Info("OLT ID: %d was retrieved.", s.Olt.ID)
logger.Info("OLT Serial-Number: %v", s.Olt.SerialNumber)
// Creating Onu Map
for intfid := uint32(0); intfid < npon; intfid++ {
- s.Onumap[intfid] = device.NewOnus(oltid, intfid, nonus, nnni)
+ s.Onumap[intfid] = device.NewOnus(oltid, intfid, nonus)
}
logger.Debug("Onu Map:")
@@ -221,7 +212,7 @@
grpcAddressPort := s.gRPCAddress + ":" + strconv.Itoa(int(s.mgmtGrpcPort))
restAddressPort := s.gRPCAddress + ":" + strconv.Itoa(int(s.mgmtRestPort))
// Start rest gateway for BBSim server
- go StartRestGatewayService(grpcAddressPort, restAddressPort, wg)
+ go StartRestGatewayService(grpcAddressPort, restAddressPort)
addressPort := s.gRPCAddress + ":" + strconv.Itoa(int(s.mgmtGrpcPort))
listener, apiserver, err := NewMgmtAPIServer(addressPort)
@@ -231,7 +222,7 @@
}
s.mgmtServer = apiserver
- pb.RegisterBBSimServiceServer(apiserver, s)
+ api.RegisterBBSimServiceServer(apiserver, s)
if e := apiserver.Serve(listener); e != nil {
logger.Error("Failed to run management api server %v", e)
return
@@ -259,17 +250,17 @@
// onu.Initialize()
// }
// }
- s.updateDevIntState(olt, device.OLT_INACTIVE)
+ s.updateDevIntState(olt, device.OltInactive)
logger.Debug("Enable() Done")
}()
logger.Debug("Enable() Start")
s.EnableServer = sv
+ flowHandler.InitializePacketInStream(*sv)
if err := s.activateOLT(*sv); err != nil {
return err
}
- s.updateDevIntState(olt, device.OLT_PREACTIVE)
-
+ s.updateDevIntState(olt, device.OltPreactive)
coreCtx := context.Background()
coreCtx, corecancel := context.WithCancel(coreCtx)
s.cancel = corecancel
@@ -279,6 +270,9 @@
if s.AutoONUActivate == true {
// Initialize all ONUs
+ // Allow some delay for OLT to become active at the VOLTHA side, before sending ONU discovery indication.
+ // Otherwise, ONU discovery indication may get processed at the VOLTHA before OLT state becomes active.
+ time.Sleep(AutoDiscoveryDelay * time.Second)
for intfid := range s.Onumap {
for _, onu := range s.Onumap[intfid] {
onu.Initialize()
@@ -308,7 +302,8 @@
s.StopPktLoops()
}
-func (s *Server) updateDevIntState(dev device.Device, state device.DeviceState) {
+func (s *Server) updateDevIntState(dev device.Device, state device.State) {
+ logger.Debug("updateDevIntState called state:%d", state)
current := dev.GetIntState()
dev.UpdateIntState(state)
logger.Debug("updateDevIntState called state: current %s, next %s", device.ONUState[current], device.ONUState[dev.GetIntState()])
@@ -322,8 +317,7 @@
}
}
-func (s *Server) updateOnuIntState(intfid uint32, onuid uint32, state device.DeviceState) error {
-
+func (s *Server) updateOnuIntState(intfid uint32, onuid uint32, state device.State) error {
onu, err := s.GetOnuByID(onuid, intfid)
if err != nil {
@@ -376,15 +370,17 @@
logger.Debug("activateOLT() Start")
// Activate OLT
olt := s.Olt
+ olt.OperState = "up"
if err := sendOltIndUp(stream, olt); err != nil {
+ olt.OperState = "down"
return err
}
- olt.OperState = "up"
logger.Info("OLT %s sent OltInd.", olt.Name)
// OLT sends Interface Indication to Adapter
if err := sendIntfInd(stream, olt); err != nil {
logger.Error("Fail to sendIntfInd: %v", err)
+ olt.OperState = "down"
return err
}
logger.Info("OLT %s sent IntfInd.", olt.Name)
@@ -392,6 +388,7 @@
// OLT sends Operation Indication to Adapter after activating each interface
if err := sendOperInd(stream, olt); err != nil {
logger.Error("Fail to sendOperInd: %v", err)
+ olt.OperState = "down"
return err
}
logger.Info("OLT %s sent OperInd.", olt.Name)
@@ -406,9 +403,10 @@
s.Vethnames = []string{}
s.Ioinfos = []*Ioinfo{}
s.wg.Done()
- s.updateDevIntState(s.Olt, device.OLT_PREACTIVE)
+ s.updateDevIntState(s.Olt, device.OltPreactive)
logger.Debug("StartPktLoops () Done")
}()
+ go s.sendPortStats()
s.alarmCh = make(chan *openolt.Indication, 10)
go startAlarmLoop(stream, s.alarmCh)
go s.startDeviceActionLoop()
@@ -442,7 +440,7 @@
}
func createIoinfos(oltid uint32, Vethnames []string) ([]*Ioinfo, []string, error) {
- ioinfos := []*Ioinfo{}
+ var ioinfos []*Ioinfo
var err error
var handler *pcap.Handle
nniup, nnidw := makeNniName(oltid)
@@ -546,21 +544,21 @@
close(nnichannel)
}()
logger.Debug("BEFORE OLT_ACTIVE")
- s.updateDevIntState(s.Olt, device.OLT_ACTIVE)
+ s.updateDevIntState(s.Olt, device.OltActive)
logger.Debug("AFTER OLT_ACTIVE")
data := &openolt.Indication_PktInd{}
for {
select {
case msg := <-s.omciIn:
- logger.Debug("OLT %d send omci indication, IF %v (ONU-ID: %v) pkt:%x.", s.Olt.ID, msg.IntfId, msg.OnuId, msg.Pkt)
- omci := &openolt.Indication_OmciInd{OmciInd: &msg}
- if err := stream.Send(&openolt.Indication{Data: omci}); err != nil {
- logger.Error("send omci indication failed: %v", err)
+ logger.Debug("OLT %d send omciInd indication, IF %v (ONU-ID: %v) pkt:%x.", s.Olt.ID, msg.IntfId, msg.OnuId, msg.Pkt)
+ omciInd := &openolt.Indication_OmciInd{OmciInd: &msg}
+ if err := stream.Send(&openolt.Indication{Data: omciInd}); err != nil {
+ logger.Error("send omciInd indication failed: %v", err)
continue
}
case msg := <-s.eapolIn:
- intfid := msg.IntfId
- onuid := msg.OnuId
+ intfid := msg.IntfID
+ onuid := msg.OnuID
gemid, err := s.getGemPortID(intfid, onuid)
if err != nil {
logger.Error("Failed to getGemPortID intfid:%d onuid:%d", intfid, onuid)
@@ -575,8 +573,8 @@
return err
}
case msg := <-s.dhcpIn: // TODO: We should put omciIn, eapolIn, dhcpIn toghether
- intfid := msg.IntfId
- onuid := msg.OnuId
+ intfid := msg.IntfID
+ onuid := msg.OnuID
gemid, err := s.getGemPortID(intfid, onuid)
bytes := msg.Byte
pkt := gopacket.NewPacket(bytes, layers.LayerTypeEthernet, gopacket.Default)
@@ -626,12 +624,12 @@
onuid := nnipkt.Info.onuid
intfid := nnipkt.Info.intfid
onu, _ := s.GetOnuByID(onuid, intfid)
+ pkt := nnipkt.Pkt
device.LoggerWithOnu(onu).Info("Received packet from NNI in grpc Server.")
- pkt := nnipkt.Pkt
data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "nni", IntfId: intfid, Pkt: pkt.Data()}}
- if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+ if err = stream.Send(&openolt.Indication{Data: data}); err != nil {
logger.Error("Fail to send PktInd indication: %v", err)
return err
}
@@ -656,7 +654,7 @@
ethtype := pkt.EthernetType
if ethtype == layers.EthernetTypeEAPOL {
device.LoggerWithOnu(onu).Info("Received downstream packet is EAPOL.")
- eapolPkt := byteMsg{IntfId: intfid, OnuId: onuid, Byte: rawpkt.Data()}
+ eapolPkt := byteMsg{IntfID: intfid, OnuID: onuid, Byte: rawpkt.Data()}
s.eapolOut <- &eapolPkt
return nil
} else if layerDHCP := rawpkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
@@ -677,7 +675,7 @@
}
}
logger.Debug("%s", poppkt.Dump())
- dhcpPkt := byteMsg{IntfId: intfid, OnuId: onuid, Byte: poppkt.Data()}
+ dhcpPkt := byteMsg{IntfID: intfid, OnuID: onuid, Byte: poppkt.Data()}
s.dhcpOut <- &dhcpPkt
return nil
} else {
@@ -713,30 +711,24 @@
}
ioinfo, err := s.IdentifyNniIoinfo("inside")
if err != nil {
+ logger.Error("failed to get ioinfo")
return err
}
handle := ioinfo.handler
logger.Debug("%s", poppkt.Dump())
SendNni(handle, poppkt)
+ // Send packet to nni port
+ if err := flowHandler.PacketOut(poppkt, "nni", ioinfo.intfid); err != nil {
+ logger.Error("Error in sending packet to nni port")
+ }
return nil
}
-// IsAllOnuActive checks for ONU_ACTIVE state for all the onus in the map
-func IsAllOnuActive(onumap map[uint32][]*device.Onu) bool {
- for _, onus := range onumap {
- for _, onu := range onus {
- if onu.GetIntState() != device.ONU_ACTIVE {
- return false
- }
- }
- }
- return true
-}
-
+// isAllOnuOmciActive checks for OnuOmciActive state for all the onus in the map
func (s *Server) isAllOnuOmciActive() bool {
for _, onus := range s.Onumap {
for _, onu := range onus {
- if onu.GetIntState() != device.ONU_OMCIACTIVE {
+ if onu.GetIntState() != device.OnuOmciActive {
return false
}
}
@@ -754,7 +746,9 @@
logger.Error("Failed to getGemPortID: %s", err)
return 0, err
}
- gemportid = onu.GemportID
+ for _, gemports := range onu.GemPortMap {
+ return gemports[0], nil
+ }
}
return uint32(gemportid), nil
}
@@ -839,7 +833,7 @@
s.SNmap.Range(
func(key, value interface{}) bool {
onu := value.(*device.Onu)
- if onu.InternalState == device.ONU_LOS_RAISED {
+ if onu.InternalState == device.OnuLosRaised {
return true
}
@@ -876,19 +870,19 @@
// TODO all onu and olt related actions (like alarms) should be handled using this function
func (s *Server) startDeviceActionLoop() {
logger.Debug("startDeviceActionLoop invoked")
- s.deviceActionCh = make(chan *pb.DeviceAction, 10)
+ s.deviceActionCh = make(chan *api.DeviceAction, 10)
for {
logger.Debug("Action channel loop started")
select {
case Req := <-s.deviceActionCh:
- logger.Debug("Reboot Action Type: %+v", Req.DeviceAction)
+ logger.Debug("Reboot Action Type: %+v", Req.Action)
switch Req.DeviceType {
case DeviceTypeOnu:
- value, _ := s.SNmap.Load(Req.DeviceSerialNumber)
+ value, _ := s.SNmap.Load(Req.SerialNumber)
onu := value.(*device.Onu)
- if Req.DeviceAction == SoftReboot {
+ if Req.Action == SoftReboot {
s.handleONUSoftReboot(onu.IntfID, onu.OnuID)
- } else if Req.DeviceAction == HardReboot {
+ } else if Req.Action == HardReboot {
s.handleONUHardReboot(onu)
}
case DeviceTypeOlt:
@@ -900,3 +894,27 @@
}
}
}
+
+func (s *Server) sendPortStats() {
+ for {
+ for i, port := range s.Olt.NniIntfs {
+ // send nni port stats
+ logger.Debug("Sending port stats for NNI %d", port.IntfID)
+ err := sendPortStats(*s.EnableServer, &s.Olt.NniIntfs[i])
+ if err != nil {
+ logger.Error("Failed to send port stats for NNI %d", port.IntfID)
+ }
+ }
+
+ for i, port := range s.Olt.PonIntfs {
+ // send pon port stats
+ logger.Debug("Sending port stats for PON %d", port.IntfID)
+ err := sendPortStats(*s.EnableServer, &s.Olt.PonIntfs[i])
+ if err != nil {
+ logger.Error("Failed to send port stats for PON %d", port.IntfID)
+ }
+ }
+
+ time.Sleep(10 * time.Second)
+ }
+}
diff --git a/core/dhcp.go b/core/dhcp.go
index b885ec5..c4f1f9a 100644
--- a/core/dhcp.go
+++ b/core/dhcp.go
@@ -33,10 +33,10 @@
// Constants for DHCP states
const (
- DHCP_INIT clientState = iota + 1
- DHCP_SELECTING
- DHCP_REQUESTING
- DHCP_BOUND
+ DhcpInit clientState = iota + 1
+ DhcpSelecting
+ DhcpRequesting
+ DhcpBound
)
type dhcpResponder struct {
@@ -50,7 +50,7 @@
srcIP *net.IPAddr
serverIP *net.IPAddr
hostname string
- curId uint32
+ curID uint32
curState clientState
}
@@ -94,11 +94,11 @@
case msg := <-dhcpOut:
logger.Debug("Received dhcp message from dhcpOut")
- if c, ok := clients[clientKey{intfid: msg.IntfId, onuid: msg.OnuId}]; ok {
+ if c, ok := clients[clientKey{intfid: msg.IntfID, onuid: msg.OnuID}]; ok {
nextstate := respondMessage("DHCP", *c, msg, dhcpIn)
c.updateState(nextstate)
} else {
- logger.Error("Failed to find dhcp client instance intfid:%d onuid:%d", msg.IntfId, msg.OnuId)
+ logger.Error("Failed to find dhcp client instance intfid:%d onuid:%d", msg.IntfID, msg.OnuID)
}
case <-ctx.Done():
return
@@ -112,8 +112,8 @@
client := dhcpClientInstance{key: clientKey{intfid: intfid, onuid: onuid},
srcaddr: &net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, 0x07, byte(onuid)},
hostname: "voltha",
- curId: rand.Uint32(),
- curState: DHCP_INIT}
+ curID: rand.Uint32(),
+ curState: DhcpInit}
dhcp := client.createDHCPDisc()
bytes, err := client.createDHCP(dhcp)
@@ -125,9 +125,9 @@
dhcpIn := resp.dhcpIn
if err := client.sendBytes(bytes, dhcpIn); err != nil {
logger.Error("Failed to send DHCP Discovery")
- return errors.New("Failed to send DHCP Discovery")
+ return errors.New("failed to send DHCP Discovery")
}
- client.curState = DHCP_SELECTING
+ client.curState = DhcpSelecting
logger.Debug("Sending DHCP Discovery intfid:%d onuid:%d", intfid, onuid)
resp.clients[clientKey{intfid: intfid, onuid: onuid}] = &client
return nil
@@ -147,30 +147,30 @@
if dhcp.Operation == layers.DHCPOpReply && msgType == layers.DHCPMsgTypeOffer {
logger.Debug("Received DHCP Offer")
logger.Debug(recvpkt.Dump())
- if cur == DHCP_SELECTING {
+ if cur == DhcpSelecting {
senddhcp := c.createDHCPReq()
sendbytes, err := c.createDHCP(senddhcp)
if err != nil {
logger.Debug("Failed to createDHCP")
return cur, nil, err
}
- return DHCP_REQUESTING, sendbytes, nil
+ return DhcpRequesting, sendbytes, nil
}
} else if dhcp.Operation == layers.DHCPOpReply && msgType == layers.DHCPMsgTypeAck {
logger.Debug("Received DHCP Ack")
logger.Debug(recvpkt.Dump())
- if cur == DHCP_REQUESTING {
- return DHCP_BOUND, nil, nil
+ if cur == DhcpRequesting {
+ return DhcpBound, nil, nil
}
} else if dhcp.Operation == layers.DHCPOpReply && msgType == layers.DHCPMsgTypeRelease {
- if cur == DHCP_BOUND {
+ if cur == DhcpBound {
senddhcp := c.createDHCPDisc()
sendbytes, err := c.createDHCP(senddhcp)
if err != nil {
fmt.Println("Failed to createDHCP")
- return DHCP_INIT, nil, err
+ return DhcpInit, nil, err
}
- return DHCP_SELECTING, sendbytes, nil
+ return DhcpSelecting, sendbytes, nil
}
} else {
logger.Debug("Received unsupported DHCP message Operation:%d MsgType:%d", dhcp.Operation, msgType)
@@ -222,8 +222,12 @@
DstPort: 67,
}
- udpLayer.SetNetworkLayerForChecksum(ipLayer)
- if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, udpLayer, dhcp); err != nil {
+ err := udpLayer.SetNetworkLayerForChecksum(ipLayer)
+ if err != nil {
+ return nil, err
+ }
+
+ if err = gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, udpLayer, dhcp); err != nil {
return nil, err
}
@@ -237,21 +241,21 @@
HardwareType: layers.LinkTypeEthernet,
HardwareLen: 6,
HardwareOpts: 0,
- Xid: c.curId,
+ Xid: c.curID,
ClientHWAddr: *c.srcaddr,
}
}
func (c *dhcpClientInstance) createDefaultOpts() []layers.DHCPOption {
hostname := []byte(c.hostname)
- opts := []layers.DHCPOption{}
+ var opts []layers.DHCPOption
opts = append(opts, layers.DHCPOption{
Type: layers.DHCPOptHostname,
Data: hostname,
Length: uint8(len(hostname)),
})
- bytes := []byte{}
+ var bytes []byte
for _, option := range defaultParamsRequestList {
bytes = append(bytes, byte(option))
}
@@ -267,7 +271,7 @@
func (c *dhcpClientInstance) createDHCPDisc() *layers.DHCPv4 {
dhcpLayer := c.createDefaultDHCPReq()
defaultOpts := c.createDefaultOpts()
- dhcpLayer.Options = append([]layers.DHCPOption{layers.DHCPOption{
+ dhcpLayer.Options = append([]layers.DHCPOption{{
Type: layers.DHCPOptMessageType,
Data: []byte{byte(layers.DHCPMsgTypeDiscover)},
Length: 1,
@@ -311,8 +315,8 @@
func (c *dhcpClientInstance) sendBytes(bytes []byte, dhcpIn chan *byteMsg) error {
// Send our packet
- msg := byteMsg{IntfId: c.key.intfid,
- OnuId: c.key.onuid,
+ msg := byteMsg{IntfID: c.key.intfid,
+ OnuID: c.key.onuid,
Byte: bytes}
dhcpIn <- &msg
logger.Debug("sendBytes intfid:%d onuid:%d", c.key.intfid, c.key.onuid)
@@ -324,7 +328,7 @@
layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4)
dhcp, _ := layerDHCP.(*layers.DHCPv4)
if dhcp == nil {
- return nil, errors.New("Failed to extract DHCP")
+ return nil, errors.New("failed to extract DHCP")
}
return dhcp, nil
}
@@ -344,5 +348,5 @@
}
}
}
- return 0, errors.New("Failed to extract MsgType from dhcp")
+ return 0, errors.New("failed to extract MsgType from dhcp")
}
diff --git a/core/eapol.go b/core/eapol.go
index ff14509..0300141 100644
--- a/core/eapol.go
+++ b/core/eapol.go
@@ -22,7 +22,6 @@
"encoding/hex"
"errors"
"fmt"
- log "github.com/sirupsen/logrus"
"net"
"sync"
"time"
@@ -30,16 +29,17 @@
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/opencord/voltha-bbsim/common/logger"
+ log "github.com/sirupsen/logrus"
)
type clientState int
// Constants for eapol states
const (
- EAP_START clientState = iota + 1 // TODO: This state definition should support 802.1X
- EAP_RESPID
- EAP_RESPCHA
- EAP_SUCCESS
+ EapStart clientState = iota + 1 // TODO: This state definition should support 802.1X
+ EapRespid
+ EapRespcha
+ EapSuccess
)
func (eap clientState) String() string {
@@ -61,7 +61,7 @@
key clientKey
srcaddr *net.HardwareAddr
version uint8
- curId uint8
+ curID uint8
curState clientState
}
@@ -91,17 +91,17 @@
for {
select {
case msg := <-eapolOut:
- logger.Debug("Received eapol from eapolOut intfid:%d onuid:%d", msg.IntfId, msg.OnuId)
+ logger.Debug("Received eapol from eapolOut intfid:%d onuid:%d", msg.IntfID, msg.OnuID)
responder := getEAPResponder()
clients := responder.clients
- if c, ok := clients[clientKey{intfid: msg.IntfId, onuid: msg.OnuId}]; ok {
- logger.Debug("Got client intfid:%d onuid: %d (ClientID: %v)", c.key.intfid, c.key.onuid, c.curId)
+ if c, ok := clients[clientKey{intfid: msg.IntfID, onuid: msg.OnuID}]; ok {
+ logger.Debug("Got client intfid:%d onuid: %d (ClientID: %v)", c.key.intfid, c.key.onuid, c.curID)
nextstate := respondMessage("EAPOL", *c, msg, eapolIn)
c.updateState(nextstate)
} else {
logger.WithFields(log.Fields{
"clients": clients,
- }).Errorf("Failed to find eapol client instance intfid:%d onuid:%d", msg.IntfId, msg.OnuId)
+ }).Errorf("Failed to find eapol client instance intfid:%d onuid:%d", msg.IntfID, msg.OnuID)
}
case <-ctx.Done():
return
@@ -136,7 +136,7 @@
responder := getEAPResponder()
clients := responder.clients
if c, ok := clients[clientKey{intfid: intfid, onuid: onuid}]; ok {
- if c.curState == EAP_SUCCESS {
+ if c.curState == EapSuccess {
logger.WithFields(log.Fields{
"int_id": intfid,
"onu_id": onuid,
@@ -144,7 +144,7 @@
break
}
// Reset state to EAP start
- c.updateState(EAP_START)
+ c.updateState(EapStart)
} else {
logger.WithFields(log.Fields{
"clients": clients,
@@ -168,8 +168,8 @@
client := eapClientInstance{key: clientKey{intfid: intfid, onuid: onuid},
srcaddr: &net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, 0x07, byte(onuid)},
version: 1,
- curId: 0,
- curState: EAP_START}
+ curID: 0,
+ curState: EapStart}
eap := client.createEAPStart()
bytes := client.createEAPOL(eap)
@@ -191,31 +191,31 @@
if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeIdentity {
logger.Debug("Received EAP-Request/Identity")
logger.Debug(recvpkt.Dump())
- c.curId = eap.Id
- if cur == EAP_START {
+ c.curID = eap.Id
+ if cur == EapStart {
reseap := c.createEAPResID()
pkt := c.createEAPOL(reseap)
- logger.Debug("Moving from EAP_START to EAP_RESPID")
- return EAP_RESPID, pkt, nil
+ logger.Debug("Moving from EapStart to EapRespid")
+ return EapRespid, pkt, nil
}
} else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeOTP {
logger.Debug("Received EAP-Request/Challenge")
logger.Debug(recvpkt.Dump())
- if cur == EAP_RESPID {
- c.curId = eap.Id
- senddata := getMD5Data(c.curId, eap)
+ if cur == EapRespid {
+ c.curID = eap.Id
+ senddata := getMD5Data(c.curID, eap)
senddata = append([]byte{0x10}, senddata...)
sendeap := c.createEAPResCha(senddata)
pkt := c.createEAPOL(sendeap)
- logger.Debug("Moving from EAP_RESPID to EAP_RESPCHA")
- return EAP_RESPCHA, pkt, nil
+ logger.Debug("Moving from EapRespid to EapRespcha")
+ return EapRespcha, pkt, nil
}
} else if eap.Code == layers.EAPCodeSuccess && eap.Type == layers.EAPTypeNone {
logger.Debug("Received EAP-Success")
logger.Debug(recvpkt.Dump())
- if cur == EAP_RESPCHA {
- logger.Debug("Moving from EAP_RESPCHA to EAP_SUCCESS")
- return EAP_SUCCESS, nil, nil
+ if cur == EapRespcha {
+ logger.Debug("Moving from EapRespcha to EapSuccess")
+ return EapSuccess, nil, nil
}
} else {
logger.Debug("Received unsupported EAP")
@@ -242,8 +242,8 @@
func sendBytes(key clientKey, pkt []byte, chIn chan *byteMsg) error {
// Send our packet
- msg := byteMsg{IntfId: key.intfid,
- OnuId: key.onuid,
+ msg := byteMsg{IntfID: key.intfid,
+ OnuID: key.onuid,
Byte: pkt}
chIn <- &msg
logger.Debug("sendBytes intfid:%d onuid:%d", key.intfid, key.onuid)
@@ -262,12 +262,12 @@
}
if eap == nil { // EAP Start
- gopacket.SerializeLayers(buffer, options,
+ _ = gopacket.SerializeLayers(buffer, options,
ethernetLayer,
&layers.EAPOL{Version: c.version, Type: 1, Length: 0},
)
} else {
- gopacket.SerializeLayers(buffer, options,
+ _ = gopacket.SerializeLayers(buffer, options,
ethernetLayer,
&layers.EAPOL{Version: c.version, Type: 0, Length: eap.Length},
eap,
@@ -283,7 +283,7 @@
func (c *eapClientInstance) createEAPResID() *layers.EAP {
eap := layers.EAP{Code: layers.EAPCodeResponse,
- Id: c.curId,
+ Id: c.curID,
Length: 9,
Type: layers.EAPTypeIdentity,
TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
@@ -292,7 +292,7 @@
func (c *eapClientInstance) createEAPResCha(payload []byte) *layers.EAP {
eap := layers.EAP{Code: layers.EAPCodeResponse,
- Id: c.curId, Length: 22,
+ Id: c.curID, Length: 22,
Type: layers.EAPTypeOTP,
TypeData: payload}
return &eap
@@ -314,7 +314,7 @@
layerEAPOL := pkt.Layer(layers.LayerTypeEAPOL)
eapol, _ := layerEAPOL.(*layers.EAPOL)
if eapol == nil {
- return nil, errors.New("Cannot extract EAPOL")
+ return nil, errors.New("cannot extract EAPOL")
}
return eapol, nil
}
@@ -323,7 +323,7 @@
layerEAP := pkt.Layer(layers.LayerTypeEAP)
eap, _ := layerEAP.(*layers.EAP)
if eap == nil {
- return nil, errors.New("Cannot extract EAP")
+ return nil, errors.New("cannot extract EAP")
}
return eap, nil
}
diff --git a/core/grpc_service.go b/core/grpc_service.go
index 651ebc7..29c93b7 100644
--- a/core/grpc_service.go
+++ b/core/grpc_service.go
@@ -17,7 +17,6 @@
package core
import (
- "github.com/opencord/voltha-protos/go/tech_profile"
"net"
"github.com/google/gopacket"
@@ -27,6 +26,7 @@
"github.com/opencord/voltha-bbsim/device"
flowHandler "github.com/opencord/voltha-bbsim/flow"
openolt "github.com/opencord/voltha-protos/go/openolt"
+ "github.com/opencord/voltha-protos/go/tech_profile"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc"
@@ -62,6 +62,7 @@
}
if s.EnableServer != nil {
+ s.Olt.OperState = "up"
if err := sendOltIndUp(*s.EnableServer, s.Olt); err != nil {
logger.Error("Failed to send OLT UP indication for reenable OLT: %v", err)
return new(openolt.Empty), err
@@ -102,16 +103,16 @@
// ActivateOnu method handles ONU activation request from VOLTHA
func (s *Server) ActivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
- logger.Debug("OLT receives ActivateONU()")
+ logger.Trace("OLT receives ActivateONU()")
matched, exist := s.getOnuFromSNmap(onu.SerialNumber)
if !exist {
- logger.Fatal("ONU not found with serial nnumber %v", onu.SerialNumber)
+ logger.Error("ONU not found with serial nnumber %v", onu.SerialNumber)
return new(openolt.Empty), status.Errorf(codes.NotFound, "ONU not found with serial number %v", onu.SerialNumber)
}
onuid := onu.OnuId
matched.OnuID = onuid
- s.updateDevIntState(matched, device.ONU_ACTIVE)
+ s.updateDevIntState(matched, device.OnuActive)
logger.Debug("ONU IntfID: %d OnuID: %d activated succesufully.", onu.IntfId, onu.OnuId)
if err := sendOnuInd(*s.EnableServer, matched, "up", "up"); err != nil {
logger.Error("Failed to send ONU Indication intfID %d, onuID %d", matched.IntfID, matched.OnuID)
@@ -122,14 +123,29 @@
}
// CreateTrafficSchedulers method should handle TrafficScheduler creation
-func (s *Server) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
- logger.Debug("OLT receives CreateTrafficSchedulers()")
+func (s *Server) CreateTrafficSchedulers(c context.Context, traffScheduler *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
+ logger.Debug("OLT receives CreateTrafficSchedulers %v", traffScheduler)
+ onu, err := s.GetOnuByID(traffScheduler.OnuId, traffScheduler.IntfId)
+ if err != nil {
+ return new(openolt.Empty), err
+ }
+ onu.Tconts = traffScheduler
return new(openolt.Empty), nil
}
// RemoveTrafficSchedulers method should handle TrafficScheduler removal
-func (s *Server) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
- logger.Debug("OLT receives RemoveTrafficSchedulers()")
+func (s *Server) RemoveTrafficSchedulers(c context.Context, traffScheduler *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
+ logger.Debug("OLT receives RemoveTrafficSchedulers %v", traffScheduler)
+ onu, err := s.GetOnuByID(traffScheduler.OnuId, traffScheduler.IntfId)
+ if err != nil {
+ return new(openolt.Empty), err
+ }
+ for _, tcont := range traffScheduler.TrafficScheds {
+ if _, exist := onu.GemPortMap[tcont.AllocId]; exist {
+ delete(onu.GemPortMap, tcont.AllocId)
+ }
+ }
+ onu.Tconts = nil
return new(openolt.Empty), nil
}
@@ -160,7 +176,7 @@
}
// Mark ONU internal state as ONU_FREE and reset onuID
- Onu.InternalState = device.ONU_FREE
+ Onu.InternalState = device.OnuFree
Onu.OnuID = 0
// Get snMap key for the ONU serial number
@@ -172,6 +188,7 @@
return new(openolt.Empty), nil
}
+// GetOnuInfo returns ONU info to VOLTHA
func (s *Server) GetOnuInfo(c context.Context, onu *openolt.Onu) (*openolt.OnuIndication, error) {
logger.Debug("Olt receives GetOnuInfo() intfID: %d, onuID: %d", onu.IntfId, onu.OnuId)
Onu, err := s.GetOnuByID(onu.OnuId, onu.IntfId)
@@ -199,8 +216,8 @@
state := onu.GetIntState()
logger.Debug("ONU-ID: %v, ONU state: %d", msg.OnuId, state)
- // If ONU is ONU_INACTIVE, ONU_FREE or ONU_OMCI_CHANNEL_LOS_RAISED drop
- if state != device.ONU_ACTIVE && state != device.ONU_OMCIACTIVE && state != device.ONU_AUTHENTICATED {
+ // If ONU is not ACTIVE drop OMCI message
+ if state < device.OnuActive {
logger.Info("ONU (IF %v ONU-ID: %v) is not ACTIVE, so not processing OmciMsg", msg.IntfId, msg.OnuId)
return new(openolt.Empty), nil
}
@@ -208,6 +225,7 @@
return new(openolt.Empty), nil
}
+// OnuPacketOut is used by voltha to send OnuPackets to BBSIM
func (s *Server) OnuPacketOut(c context.Context, packet *openolt.OnuPacket) (*openolt.Empty, error) {
onu, err := s.GetOnuByID(packet.OnuId, packet.IntfId)
if err != nil {
@@ -225,6 +243,7 @@
return new(openolt.Empty), nil
}
+// UplinkPacketOut sends uplink packets to BBSIM
func (s *Server) UplinkPacketOut(c context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
logger.Debug("OLT %d receives UplinkPacketOut().", s.Olt.ID)
rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
@@ -238,7 +257,7 @@
func (s *Server) FlowAdd(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
logger.Debug("OLT %d receives FlowAdd() %v", s.Olt.ID, flow)
// Check if flow already present
- flowKey := FlowKey{
+ flowKey := device.FlowKey{
FlowID: flow.FlowId,
FlowDirection: flow.FlowType,
}
@@ -251,7 +270,6 @@
err := flowHandler.AddFlow(flow)
if err != nil {
logger.Error("Error in pushing flow to datapath")
- return new(openolt.Empty), err
}
// Update flowMap
@@ -259,12 +277,18 @@
onu, err := s.GetOnuByID(uint32(flow.OnuId), uint32(flow.AccessIntfId))
if err == nil {
- onu.GemportID = uint16(flow.GemportId)
-
- device.LoggerWithOnu(onu).WithFields(log.Fields{
- "olt": s.Olt.ID,
- "c_tag": flow.Action.IVid,
- }).Debug("OLT receives FlowAdd().")
+ exist := false
+ // check if gemport already present in ONU
+ for _, gemport := range onu.GemPortMap[uint32(flow.AllocId)] {
+ if gemport == uint32(flow.GemportId) {
+ exist = true
+ break
+ }
+ }
+ // if not present already, then append in gemport list
+ if !exist {
+ onu.GemPortMap[uint32(flow.AllocId)] = append(onu.GemPortMap[uint32(flow.AllocId)], uint32(flow.GemportId))
+ }
// EAPOL flow
if flow.Classifier.EthType == uint32(layers.EthernetTypeEAPOL) {
@@ -290,9 +314,8 @@
if omcistate != omci.DONE {
logger.Warn("FlowAdd() OMCI state %d is not \"DONE\"", omci.GetOnuOmciState(onu.OnuID, onu.IntfID))
}
- _ = s.updateOnuIntState(onu.IntfID, onu.OnuID, device.ONU_OMCIACTIVE)
+ _ = s.updateOnuIntState(onu.IntfID, onu.OnuID, device.OnuOmciActive)
}
-
}
// DHCP flow
@@ -305,11 +328,11 @@
if omcistate != omci.DONE {
logger.Warn("FlowAdd() OMCI state %d is not \"DONE\"", omci.GetOnuOmciState(onu.OnuID, onu.IntfID))
}
- _ = s.updateOnuIntState(onu.IntfID, onu.OnuID, device.ONU_AUTHENTICATED)
+ _ = s.updateOnuIntState(onu.IntfID, onu.OnuID, device.OnuAuthenticated)
}
}
- // Update flow ID in ONU object
- onu.FlowIDs = append(onu.FlowIDs, flow.FlowId)
+ // Update flows in ONU object
+ onu.Flows = append(onu.Flows, flowKey)
}
return new(openolt.Empty), nil
}
@@ -319,7 +342,7 @@
logger.Debug("OLT %d receives FlowRemove(): %v", s.Olt.ID, flow)
// Check if flow exists
- flowKey := FlowKey{
+ flowKey := device.FlowKey{
FlowID: flow.FlowId,
FlowDirection: flow.FlowType,
}
@@ -332,20 +355,16 @@
// Send delete flow to flowHandler
err := flowHandler.DeleteFlow(flow)
if err != nil {
- return new(openolt.Empty), err
+ logger.Error("failed to delete flow")
}
onu, err := s.GetOnuByID(uint32(flow.OnuId), uint32(flow.AccessIntfId))
if err != nil {
logger.Warn("Failed flow remove %v", err)
} else {
- // Delete flowID from onu
- onu.DeleteFlowID(flow.FlowId)
- device.LoggerWithOnu(onu).WithFields(log.Fields{
- "olt": s.Olt.ID,
- "c_tag": flow.Action.IVid,
- }).Debug("OLT receives FlowRemove().")
- logger.Debug("Flows %v in ONU %d", onu.FlowIDs, onu.OnuID)
+ // Delete flows from onu
+ onu.DeleteFlow(flowKey)
+ logger.Debug("Flows %v in onu %d", onu.Flows, onu.OnuID)
}
// Delete flow from flowMap
@@ -354,6 +373,7 @@
return new(openolt.Empty), nil
}
+// HeartbeatCheck is currently not used by voltha
func (s *Server) HeartbeatCheck(c context.Context, empty *openolt.Empty) (*openolt.Heartbeat, error) {
logger.Debug("OLT %d receives HeartbeatCheck().", s.Olt.ID)
signature := new(openolt.Heartbeat)
@@ -361,11 +381,13 @@
return signature, nil
}
+// EnablePonIf enables pon interfaces at BBSIM
func (s *Server) EnablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
logger.Debug("OLT %d receives EnablePonIf().", s.Olt.ID)
return new(openolt.Empty), nil
}
+// GetPonIf returns interface info to VOLTHA
func (s *Server) GetPonIf(c context.Context, intf *openolt.Interface) (*openolt.IntfIndication, error) {
logger.Debug("OLT %d receives GetPonIf().", s.Olt.ID)
stat := new(openolt.IntfIndication)
@@ -380,6 +402,7 @@
}
+// DisablePonIf disables pon interface at BBSIM
func (s *Server) DisablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
logger.Debug("OLT %d receives DisablePonIf().", s.Olt.ID)
return new(openolt.Empty), nil
@@ -409,7 +432,7 @@
// NewGrpcServer starts openolt gRPC server
func NewGrpcServer(addrport string) (l net.Listener, g *grpc.Server, e error) {
- logger.Debug("OpenOLT gRPC server listening %s ...", addrport)
+ logger.Info("OpenOLT gRPC server listening %s ...", addrport)
g = grpc.NewServer()
l, e = net.Listen("tcp", addrport)
return
diff --git a/core/io_info.go b/core/io_info.go
index 527aaa4..caad5ef 100644
--- a/core/io_info.go
+++ b/core/io_info.go
@@ -41,7 +41,7 @@
return ioinfo, nil
}
}
- err := errors.New("No matched Ioinfo is found")
+ err := errors.New("no matched Ioinfo is found")
logger.Error("identifyUniIoinfo %s", err)
return nil, err
}
@@ -53,7 +53,7 @@
return ioinfo, nil
}
}
- err := errors.New("No matched Ioinfo is found")
+ err := errors.New("no matched Ioinfo is found")
logger.Error("IdentifyNniIoinfo %s", err)
return nil, err
}
@@ -84,13 +84,13 @@
}
// RemoveVeth deletes veth by given name
-func RemoveVeth(name string) error {
+func RemoveVeth(name string) {
err := exec.Command("ip", "link", "del", name).Run()
if err != nil {
logger.WithField("veth", name).Error("Fail to removeVeth()", err)
+ return
}
logger.WithField("veth", name).Info("Veth was removed.")
- return err
}
// RemoveVeths deletes veth
diff --git a/core/io_worker.go b/core/io_worker.go
index 1c090a8..ec70cc9 100644
--- a/core/io_worker.go
+++ b/core/io_worker.go
@@ -33,7 +33,8 @@
logger.Debug("recvWorker runs. handler: %v", *handler)
packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
for packet := range packetSource.Packets() {
- logger.Debug("recv packet from IF: %v ", *handler)
+ logger.Debug("recv packet from IF: %v", *handler)
+ logger.Debug("Packet received %v", packet)
// logger.Println(packet.Dump())
pkt := Packet{}
pkt.Info = io
@@ -71,10 +72,14 @@
EthernetType: layer.Type,
}
buffer := gopacket.NewSerializeBuffer()
- gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
+ err := gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
ethernetLayer,
gopacket.Payload(layer.Payload),
)
+ if err != nil {
+ logger.Error("%v", err)
+ }
+
retpkt := gopacket.NewPacket(
buffer.Bytes(),
layers.LayerTypeEthernet,
@@ -102,7 +107,7 @@
}
buffer := gopacket.NewSerializeBuffer()
- gopacket.SerializeLayers(
+ err := gopacket.SerializeLayers(
buffer,
gopacket.SerializeOptions{
FixLengths: false,
@@ -111,6 +116,10 @@
dot1qLayer,
gopacket.Payload(eth.Payload),
)
+ if err != nil {
+ logger.Error("%v", err)
+ }
+
ret := gopacket.NewPacket(
buffer.Bytes(),
layers.LayerTypeEthernet,
@@ -172,13 +181,13 @@
func getVethHandler(vethname string) (*pcap.Handle, error) {
var (
- device = vethname
+ deviceName = vethname
snapshotLen int32 = 1518
promiscuous = false
err error
timeout = pcap.BlockForever
)
- handle, err := pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
+ handle, err := pcap.OpenLive(deviceName, snapshotLen, promiscuous, timeout)
if err != nil {
return nil, err
}
diff --git a/core/mediator.go b/core/mediator.go
index 0756651..97bd128 100644
--- a/core/mediator.go
+++ b/core/mediator.go
@@ -24,6 +24,7 @@
"strconv"
"strings"
"sync"
+ "syscall"
"time"
"github.com/opencord/voltha-bbsim/common/logger"
@@ -31,19 +32,21 @@
log "github.com/sirupsen/logrus"
)
+// Constants for tester mode
const (
DEFAULT Mode = iota
AAA
BOTH
)
-// Store emulation mode
+// Mode store emulation mode
type Mode int
// AutoONUActivate is flag for Auto ONU Add on/off.
var AutoONUActivate int
-type option struct {
+//Option is the structure to store the user provided flag values
+type Option struct {
address string
port uint32
mgmtGrpcPort uint32
@@ -61,9 +64,9 @@
Debuglvl string
}
-// GetOptions receives command line options and stores them in option structure
-func GetOptions() *option {
- o := new(option)
+// GetOptions receives command line options and stores them in Option structure
+func GetOptions() *Option {
+ o := new(Option)
addressport := flag.String("H", ":50060", "IP address:port")
oltid := flag.Int("id", 0, "OLT-ID")
npon := flag.Int("i", 1, "Number of PON-IF ports")
@@ -88,13 +91,25 @@
o.Debuglvl = *debg
o.oltid = uint32(*oltid)
o.npon = uint32(*npon)
+ // make sure to have at-lease 1 PON port available
+ if o.npon == 0 {
+ o.npon = 1
+ }
o.nonus = uint32(*nonus)
+ // make sure to have at-least 1 ONU is available
+ if o.nonus == 0 {
+ o.nonus = 1
+ }
o.aaawait = *aaawait
o.dhcpwait = *dhcpwait
o.dhcpservip = *dhcpservip
o.intvl = *intvl
o.interactiveOnuActivation = *interactiveOnuActivation
o.KafkaBroker = *kafkaBroker
+ // make sure that 'IP:Port' or ':Port' provided properly.
+ if !strings.Contains(*addressport, ":") {
+ log.Fatal("Invalid address given (missing colon)")
+ }
o.address = strings.Split(*addressport, ":")[0]
tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
o.port = uint32(tmp)
@@ -108,15 +123,16 @@
return o
}
-type mediator struct {
- opt *option
+//Mediator stores option, server and testmanager to mediate
+type Mediator struct {
+ opt *Option
server *Server
testmanager *TestManager
}
-// NewMediator returns a new mediator object
-func NewMediator(o *option) *mediator {
- m := new(mediator)
+// NewMediator returns a new Mediator object
+func NewMediator(o *Option) *Mediator {
+ m := new(Mediator)
m.opt = o
logger.WithFields(log.Fields{
"ip": o.address,
@@ -124,12 +140,12 @@
"pon_ports": o.npon,
"onus": o.nonus,
"mode": o.Mode,
- }).Debug("New mediator")
+ }).Debug("New Mediator")
return m
}
-// Start mediator
-func (m *mediator) Start() {
+// Start Mediator
+func (m *Mediator) Start() {
var wg sync.WaitGroup
opt := m.opt
server := NewCore(opt)
@@ -147,7 +163,7 @@
}()
c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt)
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
go func() {
defer func() {
logger.Debug("SIGINT catcher Done")
@@ -157,9 +173,15 @@
wg.Add(1)
logger.Debug("SIGINT %v", sig)
close(c)
- server.Stop() // Non-blocking
- tm.Stop() // Non-blocking
- server.stopMgmtServer()
+ server.Stop() // Non-blocking
+ err := tm.Stop() // Non-blocking
+ if err != nil {
+ logger.Error("Error stopping the TestManager %v", err)
+ }
+ err = server.stopMgmtServer()
+ if err != nil {
+ logger.Error("Error stopping the Management Server %v", err)
+ }
server.wg.Done()
return
}
@@ -169,7 +191,7 @@
}
// Mediate method is invoked on OLT and ONU state change
-func (m *mediator) Mediate() {
+func (m *Mediator) Mediate() {
defer logger.Debug("Mediate Done")
for sr := range m.server.stateRepCh {
next := sr.next
@@ -194,31 +216,37 @@
}
}
-func transitOlt(current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
+func transitOlt(current device.State, next device.State, tm *TestManager, o *Option) error {
logger.Debug("trnsitOlt called current:%d , next:%d", current, next)
- if current == device.OLT_PREACTIVE && next == device.OLT_ACTIVE {
- tm.Start()
+ if current == device.OltPreactive && next == device.OltActive {
+ err := tm.Start()
+ if err != nil {
+ logger.Error("Error starting the TestManager %v", err)
+ }
nniup, _ := makeNniName(o.oltid)
- activateDHCPServer(nniup, o.dhcpservip)
- } else if current == device.OLT_ACTIVE && next == device.OLT_PREACTIVE {
- tm.Stop()
- } else if current == device.OLT_ACTIVE && next == device.OLT_INACTIVE {
- // Reboot case
- // TODO Point of discussion
+ err = activateDHCPServer(nniup, o.dhcpservip)
+ if err != nil {
+ logger.Error("Error activating DHCP Server %v", err)
+ }
+ } else if current == device.OltActive && next == device.OltPreactive {
+ err := tm.Stop()
+ if err != nil {
+ logger.Error("Error stoping the TestManager %v", err)
+ }
}
return nil
}
-func transitOnu(key device.Devkey, previous device.DeviceState, current device.DeviceState, tm *TestManager, o *option) error {
+func transitOnu(key device.Devkey, previous device.State, current device.State, tm *TestManager, o *Option) error {
logger.Debug("transitOnu called with key: %v, previous: %s, current: %s", key, device.ONUState[previous], device.ONUState[current])
if o.Mode == AAA || o.Mode == BOTH {
- if previous == device.ONU_ACTIVE && current == device.ONU_OMCIACTIVE {
+ if previous == device.OnuActive && current == device.OnuOmciActive {
logger.Debug("Starting WPASupplicant for device %v", key)
t := tm.CreateTester("AAA", o, key, activateWPASupplicant, o.aaawait)
if err := tm.StartTester(t); err != nil {
logger.Error("Cannot Start AAA Executer error:%v", err)
}
- } else if previous == device.ONU_OMCIACTIVE && current == device.ONU_INACTIVE {
+ } else if previous == device.OnuOmciActive && current == device.OnuInactive {
if err := tm.StopTester("AAA", key); err != nil {
logger.Error("Cannot Stop AAA Executer error:%v", err)
}
@@ -226,13 +254,13 @@
}
if o.Mode == BOTH {
- if previous == device.ONU_OMCIACTIVE && current == device.ONU_AUTHENTICATED {
+ if previous == device.OnuOmciActive && current == device.OnuAuthenticated {
logger.Debug("Starting DHCP client for device %v", key)
t := tm.CreateTester("DHCP", o, key, activateDHCPClient, o.dhcpwait)
if err := tm.StartTester(t); err != nil {
logger.Error("Cannot Start DHCP Executer error:%v", err)
}
- } else if previous == device.ONU_AUTHENTICATED && current == device.ONU_INACTIVE {
+ } else if previous == device.OnuAuthenticated && current == device.OnuInactive {
if err := tm.StopTester("DHCP", key); err != nil {
logger.Error("Cannot Stop DHCP Executer error:%v", err)
}
diff --git a/core/omci.go b/core/omci.go
index 857e98e..3caed49 100644
--- a/core/omci.go
+++ b/core/omci.go
@@ -86,5 +86,16 @@
logger.Info("ONU reboot recieved")
s.handleONUSoftReboot(IntfID, OnuID)
}
+ } else if MEClass == omci.GEMPortNetworkCTP {
+ switch msgType {
+ case omci.Create:
+ logger.Info("GEMPort created")
+ gemport, err := omci.GetGemPortId(IntfID, OnuID)
+ if err != nil {
+ logger.Error("error in getting gemport %v", err)
+ return
+ }
+ logger.Info("GEM Port %d created at ONU %d intf-id %d", gemport, OnuID, IntfID)
+ }
}
}
diff --git a/core/openolt_service.go b/core/openolt_service.go
index 7c7f498..cd96970 100644
--- a/core/openolt_service.go
+++ b/core/openolt_service.go
@@ -17,14 +17,14 @@
package core
import (
-
"github.com/opencord/voltha-bbsim/common/logger"
"github.com/opencord/voltha-bbsim/device"
+ "github.com/opencord/voltha-bbsim/flow"
openolt "github.com/opencord/voltha-protos/go/openolt"
)
func sendOltIndUp(stream openolt.Openolt_EnableIndicationServer, olt *device.Olt) error {
- data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: "up"}}
+ data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: olt.OperState}}
if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
logger.Error("Failed to send OLT UP indication: %v", err)
return err
@@ -45,7 +45,7 @@
// There is no need to send IntfInd for NNI
for i := uint32(0); i < olt.NumPonIntf; i++ {
intf := olt.PonIntfs[i]
- data := &openolt.Indication_IntfInd{&openolt.IntfIndication{IntfId: intf.IntfID, OperState: intf.OperState}}
+ data := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{IntfId: intf.IntfID, OperState: intf.OperState}}
if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
logger.Error("Failed to send Intf [id: %d] indication : %v", i, err)
return err
@@ -59,7 +59,7 @@
// Send OperInd for Nni
for i := uint32(0); i < olt.NumNniIntf; i++ {
intf := olt.NniIntfs[i]
- data := &openolt.Indication_IntfOperInd{&openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
+ data := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
logger.Error("Failed to send NNI IntfOper [id: %d] indication : %v", i, err)
return err
@@ -70,7 +70,7 @@
// Send OperInd for Pon
for i := uint32(0); i < olt.NumPonIntf; i++ {
intf := olt.PonIntfs[i]
- data := &openolt.Indication_IntfOperInd{&openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
+ data := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
logger.Error("Failed to send PON IntfOper [id: %d] indication : %v", i, err)
return err
@@ -133,3 +133,12 @@
}
}
}
+
+func sendPortStats(stream openolt.Openolt_EnableIndicationServer, port *device.Port) error {
+ portStats := flow.GetPortStats(&port.PortStats)
+ portStats.IntfId = interfaceIDToPortNo(port.IntfID, port.Type)
+ data := &openolt.Indication_PortStats{
+ PortStats: portStats,
+ }
+ return stream.Send(&openolt.Indication{Data: data})
+}
diff --git a/core/tester.go b/core/tester.go
index 623447d..2f445c7 100644
--- a/core/tester.go
+++ b/core/tester.go
@@ -48,14 +48,14 @@
}
// NewTestManager returns new TestManager
-func NewTestManager(opt *option) *TestManager {
+func NewTestManager(opt *Option) *TestManager {
t := new(TestManager)
t.DhcpServerIP = opt.dhcpservip
return t
}
// CreateTester creates instance of Tester
-func (*TestManager) CreateTester(testtype string, opt *option, key device.Devkey, fn func(device.Devkey) error, waitsec int) *Tester {
+func (*TestManager) CreateTester(testtype string, opt *Option, key device.Devkey, fn func(device.Devkey) error, waitsec int) *Tester {
logger.Debug("CreateTester() called")
t := new(Tester)
t.Type = testtype
@@ -87,6 +87,7 @@
return nil
}
+// StartTester starts the test
func (tm *TestManager) StartTester(t *Tester) error {
testtype := t.Type
key := t.Key
@@ -142,15 +143,30 @@
logger.Info("TestManager Initialize () called")
pids := tm.Pid
logger.Debug("Runnig Process: %v", pids)
- KillProcesses(pids)
- exec.Command("rm", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
- exec.Command("touch", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
+
+ err := KillProcesses(pids)
+ if err != nil {
+ logger.Error("%v", err)
+ }
+
+ err = exec.Command("rm", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
+ if err != nil {
+ logger.Error("%v", err)
+ }
+
+ err = exec.Command("touch", "/var/run/dhcpd.pid").Run() // This is for DHCP server activation
+ if err != nil {
+ logger.Error("%v", err)
+ }
}
// KillProcesses kill process by specified pid
func KillProcesses(pids []int) error {
for _, pname := range pids {
- killProcess(pname)
+ err := killProcess(pname)
+ if err != nil {
+ logger.Error("%v", err)
+ }
}
return nil
}
diff --git a/device/device_olt.go b/device/device_olt.go
index b3dc2c3..719f67b 100644
--- a/device/device_olt.go
+++ b/device/device_olt.go
@@ -21,13 +21,14 @@
"sync"
)
-type DeviceState int
+//State represents the OLT States
+type State int
// Device interface provides common methods for OLT and ONU devices
type Device interface {
Initialize()
- UpdateIntState(intstate DeviceState)
- GetIntState() DeviceState
+ UpdateIntState(intstate State)
+ GetIntState() State
GetDevkey() Devkey
}
@@ -46,10 +47,10 @@
SerialNumber string
Manufacture string
Name string
- InternalState DeviceState
+ InternalState State
OperState string
- NniIntfs []nniIntf
- PonIntfs []ponIntf
+ NniIntfs []Port
+ PonIntfs []Port
HeartbeatSignature uint32
mu *sync.Mutex
}
@@ -68,21 +69,21 @@
NniLosRaised
)
-type ponIntf struct {
+// Port info for NNI and PON ports
+type Port struct {
Type string
IntfID uint32
OperState string
AlarmState AlarmState
+ PortStats PortStats
}
-type nniIntf struct {
- Type string
- IntfID uint32
- OperState string
- AlarmState AlarmState
+// PortStats for NNI and PON ports
+type PortStats struct {
+ Packets uint64
}
-// Constants for port types
+// Constants for Port types
const (
IntfPon = "pon"
IntfNni = "nni"
@@ -96,9 +97,9 @@
// Constants for OLT states
const (
- OLT_INACTIVE DeviceState = iota // OLT/ONUs are not instantiated
- OLT_PREACTIVE // Before PacketInDaemon Running
- OLT_ACTIVE // After PacketInDaemon Running
+ OltInactive State = iota // OLT/ONUs are not instantiated
+ OltPreactive // Before PacketInDaemon Running
+ OltActive // After PacketInDaemon Running
)
// OLTAlarmStateToString is used to get alarm state as string
@@ -116,12 +117,12 @@
olt.NumPonIntf = npon
olt.NumNniIntf = nnni
olt.Name = "BBSIM OLT"
- olt.InternalState = OLT_INACTIVE
+ olt.InternalState = OltInactive
olt.OperState = "up"
olt.Manufacture = "BBSIM"
olt.SerialNumber = "BBSIMOLT00" + strconv.FormatInt(int64(oltid), 10)
- olt.NniIntfs = make([]nniIntf, olt.NumNniIntf)
- olt.PonIntfs = make([]ponIntf, olt.NumPonIntf)
+ olt.NniIntfs = make([]Port, olt.NumNniIntf)
+ olt.PonIntfs = make([]Port, olt.NumPonIntf)
olt.HeartbeatSignature = oltid
olt.mu = &sync.Mutex{}
for i := uint32(0); i < olt.NumNniIntf; i++ {
@@ -141,7 +142,7 @@
// Initialize method initializes NNI and PON ports
func (olt *Olt) Initialize() {
- olt.InternalState = OLT_INACTIVE
+ olt.InternalState = OltInactive
olt.OperState = "up"
for i := uint32(0); i < olt.NumNniIntf; i++ {
olt.NniIntfs[i].IntfID = i
@@ -158,7 +159,7 @@
}
// GetIntState returns internal state of OLT
-func (olt *Olt) GetIntState() DeviceState {
+func (olt *Olt) GetIntState() State {
olt.mu.Lock()
defer olt.mu.Unlock()
return olt.InternalState
@@ -170,7 +171,7 @@
}
// UpdateIntState method updates OLT internal state
-func (olt *Olt) UpdateIntState(intstate DeviceState) {
+func (olt *Olt) UpdateIntState(intstate State) {
olt.mu.Lock()
defer olt.mu.Unlock()
olt.InternalState = intstate
diff --git a/device/device_onu.go b/device/device_onu.go
index aafa793..b0af2c2 100644
--- a/device/device_onu.go
+++ b/device/device_onu.go
@@ -22,43 +22,51 @@
"github.com/opencord/voltha-bbsim/common/logger"
openolt "github.com/opencord/voltha-protos/go/openolt"
+ techprofile "github.com/opencord/voltha-protos/go/tech_profile"
log "github.com/sirupsen/logrus"
)
// Constants for the ONU states
const (
- ONU_INACTIVE DeviceState = iota // TODO: Each stage name should be more accurate
- ONU_ACTIVE
- ONU_OMCIACTIVE
- ONU_AUTHENTICATED
- ONU_LOS_RAISED
- ONU_OMCI_CHANNEL_LOS_RAISED
- ONU_LOS_ON_OLT_PON_LOS // TODO give more suitable and crisp name
- ONU_FREE
+ OnuFree State = iota // TODO: Each stage name should be more accurate
+ OnuInactive
+ OnuLosRaised
+ OnuLosOnOltPonLos
+ OnuOmciChannelLosRaised
+ OnuActive
+ OnuOmciActive
+ OnuAuthenticated
)
// ONUState maps int value of device state to string
-var ONUState = map[DeviceState]string{
- ONU_INACTIVE: "ONU_INACTIVE",
- ONU_ACTIVE: "ONU_ACTIVE",
- ONU_OMCIACTIVE: "ONU_OMCIACTIVE",
- ONU_AUTHENTICATED: "ONU_AUTHENTICATED",
- ONU_LOS_RAISED: "ONU_LOS_RAISED",
- ONU_OMCI_CHANNEL_LOS_RAISED: "ONU_OMCI_CHANNEL_LOS_RAISED",
- ONU_LOS_ON_OLT_PON_LOS: "ONU_LOS_ON_OLT_PON_LOS",
- ONU_FREE: "ONU_FREE",
+var ONUState = map[State]string{
+ OnuFree: "ONU_FREE",
+ OnuInactive: "ONU_INACTIVE",
+ OnuLosRaised: "ONU_LOS_RAISED",
+ OnuLosOnOltPonLos: "ONU_LOS_ON_OLT_PON_LOS",
+ OnuOmciChannelLosRaised: "ONU_OMCI_CHANNEL_LOS_RAISED",
+ OnuActive: "ONU_ACTIVE",
+ OnuOmciActive: "ONU_OMCIACTIVE",
+ OnuAuthenticated: "ONU_AUTHENTICATED",
+}
+
+// FlowKey used for FlowMap key
+type FlowKey struct {
+ FlowID uint32
+ FlowDirection string
}
// Onu structure stores information of ONUs
type Onu struct {
- InternalState DeviceState
+ InternalState State
OltID uint32
IntfID uint32
OperState string
SerialNumber *openolt.SerialNumber
OnuID uint32
- GemportID uint16
- FlowIDs []uint32
+ GemPortMap map[uint32][]uint32 // alloc-id is used as key and corresponding gem-ports are stored in slice
+ Tconts *techprofile.TrafficSchedulers
+ Flows []FlowKey
mu *sync.Mutex
}
@@ -69,11 +77,11 @@
}
// NewOnus initializes and returns slice of Onu objects
-func NewOnus(oltid uint32, intfid uint32, nonus uint32, nnni uint32) []*Onu {
- onus := []*Onu{}
+func NewOnus(oltid uint32, intfid uint32, nonus uint32) []*Onu {
+ var onus []*Onu
for i := 1; i <= int(nonus); i++ {
onu := Onu{}
- onu.InternalState = ONU_FREE // New Onu Initialised with state ONU_FREE
+ onu.InternalState = OnuFree // New Onu Initialised with state ONU_FREE
onu.mu = &sync.Mutex{}
onu.IntfID = intfid
onu.OltID = oltid
@@ -81,7 +89,7 @@
onu.SerialNumber = new(openolt.SerialNumber)
onu.SerialNumber.VendorId = []byte("BBSM")
onu.SerialNumber.VendorSpecific = NewSN(oltid, intfid, uint32(i))
- onu.GemportID = 0
+ onu.GemPortMap = make(map[uint32][]uint32)
onus = append(onus, &onu)
}
return onus
@@ -90,19 +98,7 @@
// Initialize method initializes ONU state to up and ONU_INACTIVE
func (onu *Onu) Initialize() {
onu.OperState = "up"
- onu.InternalState = ONU_INACTIVE
-}
-
-// ValidateONU method validate ONU based on the serial number in onuMap
-func ValidateONU(targetonu openolt.Onu, regonus map[uint32][]*Onu) bool {
- for _, onus := range regonus {
- for _, onu := range onus {
- if ValidateSN(*targetonu.SerialNumber, *onu.SerialNumber) {
- return true
- }
- }
- }
- return false
+ onu.InternalState = OnuInactive
}
// ValidateSN compares two serial numbers and returns result as true/false
@@ -120,7 +116,7 @@
}
// UpdateIntState method updates ONU internal state
-func (onu *Onu) UpdateIntState(intstate DeviceState) {
+func (onu *Onu) UpdateIntState(intstate State) {
onu.mu.Lock()
defer onu.mu.Unlock()
onu.InternalState = intstate
@@ -132,21 +128,21 @@
}
// GetIntState returns ONU internal state
-func (onu *Onu) GetIntState() DeviceState {
+func (onu *Onu) GetIntState() State {
onu.mu.Lock()
defer onu.mu.Unlock()
return onu.InternalState
}
-// DeleteFlowID method search and delete flowID from the onu flowIDs slice
-func (onu *Onu) DeleteFlowID(flowID uint32) {
- for pos, id := range onu.FlowIDs {
- if id == flowID {
- // delete the flowID by shifting all flowIDs by one
- onu.FlowIDs = append(onu.FlowIDs[:pos], onu.FlowIDs[pos+1:]...)
- t := make([]uint32, len(onu.FlowIDs))
- copy(t, onu.FlowIDs)
- onu.FlowIDs = t
+// DeleteFlow method search and delete flowKey from the onu flows slice
+func (onu *Onu) DeleteFlow(key FlowKey) {
+ for pos, flowKey := range onu.Flows {
+ if flowKey == key {
+ // delete the flowKey by shifting all flowKeys by one
+ onu.Flows = append(onu.Flows[:pos], onu.Flows[pos+1:]...)
+ t := make([]FlowKey, len(onu.Flows))
+ copy(t, onu.Flows)
+ onu.Flows = t
break
}
}
diff --git a/device/utils.go b/device/utils.go
index 7e0eca3..2d4cc28 100644
--- a/device/utils.go
+++ b/device/utils.go
@@ -17,19 +17,17 @@
package device
import (
- "fmt"
-
"github.com/opencord/voltha-bbsim/common/logger"
log "github.com/sirupsen/logrus"
"strconv"
)
+// OnuToSn returns serial number in string format for given ONU
func OnuToSn(onu *Onu) string {
- // FIXME
- // see https://github.com/opencord/voltha/blob/master/voltha/adapters/openolt/openolt_device.py#L929-L943
- return string(onu.SerialNumber.VendorId) + "00000" + fmt.Sprint(onu.IntfID) + "0" + fmt.Sprintf("%x", onu.OnuID-1)
+ return string(onu.SerialNumber.VendorId) + ConvB2S(onu.SerialNumber.VendorSpecific)
}
+// LoggerWithOnu method logs ONU fields
func LoggerWithOnu(onu *Onu) *log.Entry {
if onu == nil {
@@ -39,12 +37,13 @@
return logger.GetLogger().WithFields(log.Fields{
"serial_number": OnuToSn(onu),
- "interfaceId": onu.IntfID,
- "onuId": onu.OnuID,
- "oltId": onu.OltID,
+ "interfaceID": onu.IntfID,
+ "onuID": onu.OnuID,
+ "oltID": onu.OltID,
})
}
+// ConvB2S converts byte array to string
func ConvB2S(b []byte) string {
s := ""
for _, i := range b {
diff --git a/flow/flow.go b/flow/flow.go
index f1d6e10..7e47db9 100644
--- a/flow/flow.go
+++ b/flow/flow.go
@@ -17,20 +17,28 @@
package flow
import (
+ "math/rand"
+ "time"
+
+ "github.com/google/gopacket"
"github.com/opencord/voltha-bbsim/common/logger"
+ "github.com/opencord/voltha-bbsim/device"
openolt "github.com/opencord/voltha-protos/go/openolt"
log "github.com/sirupsen/logrus"
)
-var flowManager FlowManager
+var flowManager Manager
-// FlowManager interface for common methods of controller
-type FlowManager interface {
+// Manager interface for common methods of controller
+type Manager interface {
AddFlow(flow *openolt.Flow) error
DeleteFlow(flow *openolt.Flow) error
+ DeleteAllFlows() error
PortUp(portID uint32) error
PortDown(portID uint32) error
GetFlow(onuID uint32) ([]*openolt.Flow, error)
+ InitializePacketInStream(s openolt.Openolt_EnableIndicationServer)
+ PacketOut(packet gopacket.Packet, s string, u uint32) error
}
// DefaultFlowController empty struct
@@ -45,6 +53,11 @@
return
}
+// InitializePacketInStream initializes the stream to send packets towards VOLTHA
+func InitializePacketInStream(s openolt.Openolt_EnableIndicationServer) {
+ flowManager.InitializePacketInStream(s)
+}
+
// AddFlow abstracts actual implementation of flow addition
func AddFlow(flow *openolt.Flow) error {
return flowManager.AddFlow(flow)
@@ -55,6 +68,11 @@
return flowManager.DeleteFlow(flow)
}
+// DeleteAllFlows abstracts actual implementation of flow deletion
+func DeleteAllFlows() error {
+ return flowManager.DeleteAllFlows()
+}
+
// PortUp abstracts actual implementation of port up
func PortUp(portID uint32) error {
return flowManager.PortUp(portID)
@@ -65,8 +83,43 @@
return flowManager.PortDown(portID)
}
+// PacketOut abstracts actual implementation of sending packet out
+func PacketOut(packet gopacket.Packet, intfType string, intfID uint32) error {
+ return flowManager.PacketOut(packet, intfType, intfID)
+}
+
+// GetPortStats return stats for specified interface
+func GetPortStats(portStats *device.PortStats) *openolt.PortStatistics {
+
+ // increment current packet count by random number
+ pkts := portStats.Packets + uint64((rand.Intn(50)+1)*10)
+ portStats.Packets = pkts
+ logger.Info("Packet count %d", portStats.Packets)
+
+ // fill all other stats based on packet count
+ nextPortStats := &openolt.PortStatistics{
+ RxBytes: pkts * 64,
+ RxPackets: pkts,
+ RxUcastPackets: pkts * 40 / 100,
+ RxMcastPackets: pkts * 30 / 100,
+ RxBcastPackets: pkts * 30 / 100,
+ RxErrorPackets: 0,
+ TxBytes: pkts * 64,
+ TxPackets: pkts,
+ TxUcastPackets: pkts * 40 / 100,
+ TxMcastPackets: pkts * 30 / 100,
+ TxBcastPackets: pkts * 30 / 100,
+ TxErrorPackets: 0,
+ RxCrcErrors: 0,
+ BipErrors: 0,
+ Timestamp: uint32(time.Now().Unix()),
+ }
+
+ return nextPortStats
+}
+
// InitializeDefaultFlowController method to initialize default controller
-func InitializeDefaultFlowController() FlowManager {
+func InitializeDefaultFlowController() Manager {
logger.Debug("Default controller initialized")
return new(DefaultFlowController)
}
@@ -90,6 +143,12 @@
return nil
}
+// DeleteAllFlows implemented for DefaultFlowController
+func (fc *DefaultFlowController) DeleteAllFlows() error {
+ logger.Debug("DeleteAllFlows invoked")
+ return nil
+}
+
// GetFlow implemented for DefaultFlowController
func (fc *DefaultFlowController) GetFlow(onuID uint32) ([]*openolt.Flow, error) {
return nil, nil
@@ -106,3 +165,14 @@
logger.Debug("PortDown invoked %d", portID)
return nil
}
+
+// InitializePacketInStream implemented for DefaultFlowController
+func (fc *DefaultFlowController) InitializePacketInStream(s openolt.Openolt_EnableIndicationServer) {
+ logger.Debug("Initialize Openolt stream")
+}
+
+// PacketOut implemented for DefaultFlowController
+func (fc *DefaultFlowController) PacketOut(pkt gopacket.Packet, intfType string, intfID uint32) error {
+ logger.Debug("PacketOut invoked intfType: %s, intfID: %d", intfType, intfID)
+ return nil
+}