[VOL-2974] - drive the adapter implementation forward to reach active OperState of ONU UNI ports
[VOL-2978] - MibSync - Store selected MEs received from ONUs during Mib-Upload
Change-Id: If391bf02adc05bf0b0ecd78c52a5407805981745
Signed-off-by: Holger Hildebrandt <holger.hildebrandt@adtran.com>
diff --git a/VERSION b/VERSION
index 7a8795e..9e2143d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.3-dev
+0.1.6-dev
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 21e72fc..2486127 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -22,6 +22,8 @@
"encoding/hex"
"errors"
"fmt"
+ "strconv"
+ "strings"
"sync"
"time"
@@ -30,7 +32,9 @@
"github.com/looplab/fsm"
"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
+ vc "github.com/opencord/voltha-protos/v3/go/common"
ic "github.com/opencord/voltha-protos/v3/go/inter_container"
+ of "github.com/opencord/voltha-protos/v3/go/openflow_13"
oop "github.com/opencord/voltha-protos/v3/go/openolt"
"github.com/opencord/voltha-protos/v3/go/voltha"
)
@@ -43,6 +47,28 @@
)
*/
+//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
+const (
+ pon = voltha.EventSubCategory_PON
+ olt = voltha.EventSubCategory_OLT
+ ont = voltha.EventSubCategory_ONT
+ onu = voltha.EventSubCategory_ONU
+ nni = voltha.EventSubCategory_NNI
+ service = voltha.EventCategory_SERVICE
+ security = voltha.EventCategory_SECURITY
+ equipment = voltha.EventCategory_EQUIPMENT
+ processing = voltha.EventCategory_PROCESSING
+ environment = voltha.EventCategory_ENVIRONMENT
+ communication = voltha.EventCategory_COMMUNICATION
+)
+
+const (
+ cEventObjectType = "ONU"
+)
+const (
+ cOnuActivatedEvent = "ONU_ACTIVATED"
+)
+
//DeviceHandler will interact with the ONU ? device.
type DeviceHandler struct {
deviceID string
@@ -52,6 +78,8 @@
logicalDeviceID string
ProxyAddressID string
ProxyAddressType string
+ parentId string
+ ponPortNumber uint32
coreProxy adapterif.CoreProxy
AdapterProxy adapterif.AdapterProxy
@@ -62,6 +90,7 @@
pOnuOmciDevice *OnuDeviceEntry
exitChannel chan int
lockDevice sync.RWMutex
+ pOnuIndication *oop.OnuIndication
//Client oop.OpenoltClient
//clientCon *grpc.ClientConn
@@ -76,35 +105,9 @@
stopCollector chan bool
stopHeartbeatCheck chan bool
activePorts sync.Map
- uniEntityMap map[uint16]*OnuUniPort
+ uniEntityMap map[uint32]*OnuUniPort
}
-/*
-//OnuDevice represents ONU related info
-type OnuDevice struct {
- deviceID string
- deviceType string
- serialNumber string
- onuID uint32
- intfID uint32
- proxyDeviceID string
- uniPorts map[uint32]struct{}
-}
-
-//NewOnuDevice creates a new Onu Device
-func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string) *OnuDevice {
- var device OnuDevice
- device.deviceID = devID
- device.deviceType = deviceTp
- device.serialNumber = serialNum
- device.onuID = onuID
- device.intfID = intfID
- device.proxyDeviceID = proxyDevID
- device.uniPorts = make(map[uint32]struct{})
- return &device
-}
-*/
-
//NewDeviceHandler creates a new device handler
func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *DeviceHandler {
var dh DeviceHandler
@@ -124,7 +127,7 @@
//dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
dh.activePorts = sync.Map{}
//TODO initialize the support classes.
- dh.uniEntityMap = make(map[uint16]*OnuUniPort)
+ dh.uniEntityMap = make(map[uint32]*OnuUniPort)
// Device related state machine
dh.pDeviceStateFsm = fsm.NewFSM(
@@ -207,9 +210,7 @@
switch msgType {
case ic.InterAdapterMessageType_OMCI_REQUEST:
{
- /* TOBECHECKED: I assume, ONU Adapter receives the message hier already 'unmarshalled'? else: (howTo?)*/
msgBody := msg.GetBody()
-
omciMsg := &ic.InterAdapterOmciMessage{}
if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{"error": err})
@@ -225,9 +226,7 @@
}
case ic.InterAdapterMessageType_ONU_IND_REQUEST:
{
- /* TOBECHECKED: I assume, ONU Adapter receives the message hier already 'unmarshalled'? else: see above omci block */
msgBody := msg.GetBody()
-
onu_indication := &oop.OnuIndication{}
if err := ptypes.UnmarshalAny(msgBody, onu_indication); err != nil {
logger.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{"error": err})
@@ -287,6 +286,53 @@
return nil
}
+func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device,
+ portNo int64) (*ic.PortCapability, error) {
+ logger.Debugw("GetOfpPortInfo start", log.Fields{"deviceID": device.Id, "portNo": portNo})
+
+ //function body as per OLTAdapter handler code
+ // adapted with values from py dapter code
+ if pUniPort, exist := dh.uniEntityMap[uint32(portNo)]; exist {
+ var macOctets [6]uint8
+ macOctets[5] = 0x08
+ macOctets[4] = uint8(dh.ponPortNumber >> 8)
+ macOctets[3] = uint8(dh.ponPortNumber)
+ macOctets[2] = uint8(portNo >> 16)
+ macOctets[1] = uint8(portNo >> 8)
+ macOctets[0] = uint8(portNo)
+ hwAddr := genMacFromOctets(macOctets)
+ capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
+ name := device.SerialNumber + "-" + strconv.FormatUint(uint64(pUniPort.macBpNo), 10)
+ ofUniPortState := of.OfpPortState_OFPPS_LINK_DOWN
+ if pUniPort.operState == vc.OperStatus_ACTIVE {
+ ofUniPortState = of.OfpPortState_OFPPS_LIVE
+ }
+ logger.Debugw("setting LogicalPort", log.Fields{"with-name": name,
+ "withUniPort": pUniPort.name, "withMacBase": hwAddr, "OperState": ofUniPortState})
+
+ return &ic.PortCapability{
+ Port: &voltha.LogicalPort{
+ OfpPort: &of.OfpPort{
+ Name: name,
+ //HwAddr: macAddressToUint32Array(dh.device.MacAddress),
+ HwAddr: macAddressToUint32Array(hwAddr),
+ Config: 0,
+ State: uint32(ofUniPortState),
+ Curr: capacity,
+ Advertised: capacity,
+ Peer: capacity,
+ CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+ MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
+ },
+ DeviceId: device.Id,
+ DevicePortNo: uint32(portNo),
+ },
+ }, nil
+ }
+ logger.Warnw("No UniPort found - abort", log.Fields{"for PortNo": uint32(portNo)})
+ return nil, errors.New("UniPort not found")
+}
+
// DeviceHandler methods that implement the adapters interface requests## end #########
// #####################################################################################
@@ -303,31 +349,24 @@
logger.Debug("doStateInit-started")
var err error
- /*
- var err error
- dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock())
- if err != nil {
- logger.Errorw("Failed to dial device", log.Fields{"DeviceId": dh.deviceID, "HostAndPort": dh.device.GetHostAndPort(), "err": err})
- return err
- }
- return nil
- */
-
// populate what we know. rest comes later after mib sync
dh.device.Root = false
dh.device.Vendor = "OpenONU"
dh.device.Model = "go"
dh.device.Reason = "activating-onu"
- dh.logicalDeviceID = dh.deviceID
+ dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
+ dh.parentId = dh.device.ParentId
+ dh.ponPortNumber = dh.device.ParentPortNo
+
// store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
logger.Debugw("device-updated", log.Fields{"deviceID": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
"proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
- "ParentId": dh.device.ParentId, "ParentPortNo": dh.device.ParentPortNo})
+ "ParentId": dh.parentId, "ParentPortNo": dh.ponPortNumber})
/*
self._pon = PonPort.create(self, self._pon_port_number)
@@ -339,18 +378,18 @@
)
*/
logger.Debug("adding-pon-port")
- pPonPortNo := uint32(1)
- if dh.device.ParentPortNo != 0 {
- pPonPortNo = dh.device.ParentPortNo
+ var ponPortNo uint32 = 1
+ if dh.ponPortNumber != 0 {
+ ponPortNo = dh.ponPortNumber
}
pPonPort := &voltha.Port{
- PortNo: pPonPortNo,
- Label: fmt.Sprintf("pon-%d", pPonPortNo),
+ PortNo: ponPortNo,
+ Label: fmt.Sprintf("pon-%d", ponPortNo),
Type: voltha.Port_PON_ONU,
OperStatus: voltha.OperStatus_ACTIVE,
- Peers: []*voltha.Port_PeerPort{{DeviceId: dh.device.ParentId, // Peer device is OLT
- PortNo: dh.device.ParentPortNo}}, // Peer port is parent's port number
+ Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentId, // Peer device is OLT
+ PortNo: ponPortNo}}, // Peer port is parent's port number
}
if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
@@ -463,10 +502,10 @@
logger.Debug("doStateDown-started")
var err error
- device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
- if err != nil || device == nil {
+ device := dh.device
+ if device == nil {
/*TODO: needs to handle error scenarios */
- logger.Errorw("Failed to fetch device device", log.Fields{"err": err})
+ logger.Error("Failed to fetch handler device")
e.Cancel(err)
return
}
@@ -573,18 +612,28 @@
// doStateInit provides the device update to the core
func (dh *DeviceHandler) create_interface(onuind *oop.OnuIndication) error {
- logger.Debug("create_interface-started - not yet fully implemented (only device state update)")
+ logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
+ "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
+
+ dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
logger.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.deviceID, "error": err})
}
- device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
- if err != nil || device == nil {
- /*TODO: needs to handle error scenarios */
- logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
- return errors.New("Voltha Device not found")
- }
+ // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
+ // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
+ // in python code it looks as the started onu_omci_device might have been updated with some new instance state of the core device
+ // but I would not know why, and the go code anyway dows not work with the device directly anymore in the OnuDeviceEntry
+ // so let's just try to keep it simple ...
+ /*
+ device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
+ if err != nil || device == nil {
+ //TODO: needs to handle error scenarios
+ logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
+ return errors.New("Voltha Device not found")
+ }
+ */
dh.GetOnuDeviceEntry().Start(context.TODO())
if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
@@ -739,19 +788,25 @@
func (dh *DeviceHandler) DeviceStateUpdate(dev_Event OnuDeviceEvent) {
if dev_Event == MibDatabaseSync {
- logger.Debug("MibInSync event: update dev state to 'MibSync complete'")
+ logger.Debugw("MibInSync event: update dev state to 'MibSync complete'", log.Fields{"deviceID": dh.deviceID})
//initiate DevStateUpdate
if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{"deviceID": dh.deviceID, "error": err})
}
+ for i := uint16(0); i < dh.GetOnuDeviceEntry().pOnuDB.unigMeCount; i++ {
+ mgmtEntityId, _ := dh.GetOnuDeviceEntry().pOnuDB.unigMe[i].GetAttribute("ManagedEntityId")
+ logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{"deviceId": dh.GetOnuDeviceEntry().deviceID, "UnigMe EntityID": mgmtEntityId})
+ dh.addUniPort(mgmtEntityId.(uint16), i, UniPPTP)
+ }
+
// fixed assumption about PPTP/UNI-G ONU-config
// to be replaced by DB parsing of MibUpload data TODO!!!
// parameters are: InstanceNo, running UniNo, type
- dh.addUniPort(257, 0, UniPPTP)
- dh.addUniPort(258, 1, UniPPTP)
- dh.addUniPort(259, 2, UniPPTP)
- dh.addUniPort(260, 3, UniPPTP)
+ // dh.addUniPort(257, 0, UniPPTP)
+ // dh.addUniPort(258, 1, UniPPTP)
+ // dh.addUniPort(259, 2, UniPPTP)
+ // dh.addUniPort(260, 3, UniPPTP)
// start the MibDownload (assumed here to be done via some FSM again - open //TODO!!!)
/* the mib-download code may look something like that:
@@ -778,46 +833,126 @@
//shortcut code to fake download-done!!!:
go dh.GetOnuDeviceEntry().transferSystemEvent(MibDownloadDone)
} else if dev_Event == MibDownloadDone {
- logger.Debug("MibDownloadDone event: update dev state to 'Oper.Active'")
+ logger.Debugw("MibDownloadDone event: update dev state to 'Oper.Active'", log.Fields{"deviceID": dh.deviceID})
//initiate DevStateUpdate
if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
logger.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.deviceID, "error": err})
}
- logger.Debug("MibDownloadDone Event: update dev reasone to 'initial-mib-downloaded'")
+ logger.Debug("MibDownloadDone Event: update dev reason to 'initial-mib-downloaded'")
if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
log.Fields{"deviceID": dh.deviceID, "error": err})
}
- //TODO !!! following activities according to python code:
- /*
- yield self.enable_ports()
- self._mib_download_task = None
- yield self.onu_active_event() -> with 'OnuActiveEvent' !!! might be this is required for ONOS visibility??
- */
+ go dh.enableUniPortStateUpdate(dh.deviceID) //cmp python yield self.enable_ports()
+
+ raisedTs := time.Now().UnixNano()
+ go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
} else {
- logger.Warnw("unhandled-device-event", log.Fields{"event": dev_Event})
+ logger.Warnw("unhandled-device-event", log.Fields{"deviceID": dh.deviceID, "event": dev_Event})
}
}
func (dh *DeviceHandler) addUniPort(a_uniInstNo uint16, a_uniId uint16, a_portType UniPortType) {
- if _, present := dh.uniEntityMap[a_uniInstNo]; present {
+ // parameters are IntfId, OnuId, uniId
+ uniNo := MkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
+ uint32(a_uniId))
+ if _, present := dh.uniEntityMap[uniNo]; present {
logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": a_uniInstNo})
} else {
- //TODO: need to find the ONU intfId and OnuId, using hard coded values for single ONU test!!!
- // parameters are IntfId, OnuId, uniId
- uni_no := MkUniPortNum(0, 1, uint32(a_uniId))
//with arguments a_uniId, a_portNo, a_portType
- pUniPort := NewOnuUniPort(a_uniId, uni_no, a_uniInstNo, a_portType)
+ pUniPort := NewOnuUniPort(a_uniId, uniNo, a_uniInstNo, a_portType)
if pUniPort == nil {
logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": a_uniInstNo})
} else {
- dh.uniEntityMap[a_uniInstNo] = pUniPort
+ //store UniPort with the System-PortNumber key
+ dh.uniEntityMap[uniNo] = pUniPort
// create announce the UniPort to the core as VOLTHA Port object
- if err := pUniPort.CreateVolthaPort(dh); err != nil {
- logger.Infow("onuUniPort-added", log.Fields{"for InstanceId": a_uniInstNo})
- } //error looging already within UniPort method
+ if err := pUniPort.CreateVolthaPort(dh); err == nil {
+ logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
+ } //error logging already within UniPort method
}
}
}
+
+// Enable listen on UniPortState changes and update core port state accordingly
+func (dh *DeviceHandler) enableUniPortStateUpdate(a_deviceID string) {
+ // TODO!!!: In py code the PPTP UNI states are updated based on event notifications (from where?)
+ // these notifcations are handled in port_state_handler() to transfer core states ACTIVE or UNKNOWN
+ // For VEIP ports enale_ports() directly sets ACTIVE (forced)
+ // to shortcut processing temporarily here we set the OperState ACTIVE here forced generally for the moment
+ for uniNo, uniPort := range dh.uniEntityMap {
+ logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
+ uniPort.SetOperState(vc.OperStatus_ACTIVE)
+ //maybe also use getter funvtions on uniPort - perhaps later ...
+ go dh.coreProxy.PortStateUpdate(context.TODO(), a_deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
+ }
+}
+
+// ONU_Active/Inactive announcement on system KAFKA bus
+// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
+func (dh *DeviceHandler) sendOnuOperStateEvent(a_OperState vc.OperStatus_Types, a_deviceID string, raisedTs int64) {
+ var de voltha.DeviceEvent
+ eventContext := make(map[string]string)
+ //Populating event context
+ // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
+ parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentId, dh.parentId)
+ if err != nil || parentDevice == nil {
+ logger.Errorw("Failed to fetch parent device for OnuEvent",
+ log.Fields{"parentId": dh.parentId, "err": err})
+ }
+ oltSerialNumber := parentDevice.SerialNumber
+
+ eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
+ eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
+ eventContext["serial-number"] = dh.device.SerialNumber
+ eventContext["olt_serial_number"] = oltSerialNumber
+ eventContext["device_id"] = a_deviceID
+ eventContext["registration_id"] = a_deviceID //py: string(device_id)??
+ logger.Debugw("prepare ONU_ACTIVATED event",
+ log.Fields{"DeviceId": a_deviceID, "EventContext": eventContext})
+
+ /* Populating device event body */
+ de.Context = eventContext
+ de.ResourceId = a_deviceID
+ if a_OperState == voltha.OperStatus_ACTIVE {
+ de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
+ de.Description = fmt.Sprintf("%s Event - %s - %s",
+ cEventObjectType, cOnuActivatedEvent, "Raised")
+ } else {
+ de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
+ de.Description = fmt.Sprintf("%s Event - %s - %s",
+ cEventObjectType, cOnuActivatedEvent, "Cleared")
+ }
+ /* Send event to KAFKA */
+ if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
+ logger.Warnw("could not send ONU_ACTIVATED event",
+ log.Fields{"DeviceId": a_deviceID, "error": err})
+ }
+ logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
+ log.Fields{"DeviceId": a_deviceID, "with-EventName": de.DeviceEventName})
+}
+
+/* *********************************************************** */
+
+func genMacFromOctets(a_octets [6]uint8) string {
+ return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
+ a_octets[5], a_octets[4], a_octets[3],
+ a_octets[2], a_octets[1], a_octets[0])
+}
+
+//copied from OLT Adapter: unify centrally ?
+func macAddressToUint32Array(mac string) []uint32 {
+ slist := strings.Split(mac, ":")
+ result := make([]uint32, len(slist))
+ var err error
+ var tmp int64
+ for index, val := range slist {
+ if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
+ return []uint32{1, 2, 3, 4, 5, 6}
+ }
+ result[index] = uint32(tmp)
+ }
+ return result
+}
diff --git a/internal/pkg/onuadaptercore/mib_sync.go b/internal/pkg/onuadaptercore/mib_sync.go
index 45c771b..ba4c429 100644
--- a/internal/pkg/onuadaptercore/mib_sync.go
+++ b/internal/pkg/onuadaptercore/mib_sync.go
@@ -42,6 +42,8 @@
func (onuDeviceEntry *OnuDeviceEntry) enterStartingState(e *fsm.Event) {
logger.Debugw("MibSync FSM", log.Fields{"Start processing MibSync-msgs in State": e.FSM.Current(), "device-id": onuDeviceEntry.deviceID})
+ onuDeviceEntry.pOnuDB = NewOnuDeviceDB(context.TODO(), onuDeviceEntry)
+
// create channel and start go routine for processing of MibSync messages
onuDeviceEntry.MibSyncChan = make(chan Message, 2048)
go onuDeviceEntry.ProcessMibSyncMessages()
@@ -162,13 +164,13 @@
logger.Error("Omci Msg layer could not be assigned")
return
}
- logger.Debugw("MibUploadResponse Data for:", log.Fields{"deviceId": onuDeviceEntry.PDevOmciCC.deviceID, "data-fields": msgObj})
+ logger.Debugw("MibUploadResponse Data for:", log.Fields{"deviceId": onuDeviceEntry.deviceID, "data-fields": msgObj})
/* to be verified / reworked !!! */
onuDeviceEntry.PDevOmciCC.uploadNoOfCmds = msgObj.NumberOfCommands
if onuDeviceEntry.PDevOmciCC.uploadSequNo < onuDeviceEntry.PDevOmciCC.uploadNoOfCmds {
onuDeviceEntry.PDevOmciCC.sendMibUploadNext(context.TODO(), ConstDefaultOmciTimeout, true)
} else {
- logger.Error("Invalid number of commands received for:", log.Fields{"deviceId": onuDeviceEntry.PDevOmciCC.deviceID, "uploadNoOfCmds": onuDeviceEntry.PDevOmciCC.uploadNoOfCmds})
+ logger.Error("Invalid number of commands received for:", log.Fields{"deviceId": onuDeviceEntry.deviceID, "uploadNoOfCmds": onuDeviceEntry.PDevOmciCC.uploadNoOfCmds})
//TODO right action?
onuDeviceEntry.MibSyncFsm.Event("timeout")
}
@@ -183,8 +185,10 @@
logger.Error("Omci Msg layer could not be assigned")
return
}
- logger.Debugw("MibUploadNextResponse Data for:", log.Fields{"deviceId": onuDeviceEntry.PDevOmciCC.deviceID, "data-fields": msgObj})
- // TODO !!! content evaluation ?????
+ logger.Debugw("MibUploadNextResponse Data for:", log.Fields{"deviceId": onuDeviceEntry.deviceID, "data-fields": msgObj})
+
+ onuDeviceEntry.pOnuDB.StoreMe(msgObj)
+
if onuDeviceEntry.PDevOmciCC.uploadSequNo < onuDeviceEntry.PDevOmciCC.uploadNoOfCmds {
onuDeviceEntry.PDevOmciCC.sendMibUploadNext(context.TODO(), ConstDefaultOmciTimeout, true)
} else {
diff --git a/internal/pkg/onuadaptercore/onu_device_db.go b/internal/pkg/onuadaptercore/onu_device_db.go
new file mode 100644
index 0000000..2729747
--- /dev/null
+++ b/internal/pkg/onuadaptercore/onu_device_db.go
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//Package adaptercoreonu provides the utility for onu devices, flows and statistics
+package adaptercoreonu
+
+import (
+ "context"
+ "errors"
+
+ "github.com/opencord/omci-lib-go"
+ me "github.com/opencord/omci-lib-go/generated"
+ "github.com/opencord/voltha-lib-go/v3/pkg/log"
+)
+
+//OnuDeviceDB structure holds information about known ME's
+type OnuDeviceDB struct {
+ ctx context.Context
+ pOnuDeviceEntry *OnuDeviceEntry
+ unigMeCount uint16
+ unigMe []*me.ManagedEntity
+ pptpEthUniMeCount uint16
+ pptpEthUniMe []*me.ManagedEntity
+ AnigMe *me.ManagedEntity
+ VeipMe *me.ManagedEntity
+}
+
+//OnuDeviceDB returns a new instance for a specific ONU_Device_Entry
+func NewOnuDeviceDB(ctx context.Context, a_pOnuDeviceEntry *OnuDeviceEntry) *OnuDeviceDB {
+ logger.Debugw("Init OnuDeviceDB for:", log.Fields{"deviceId": a_pOnuDeviceEntry.deviceID})
+ var onuDeviceDB OnuDeviceDB
+ onuDeviceDB.ctx = ctx
+ onuDeviceDB.pOnuDeviceEntry = a_pOnuDeviceEntry
+ onuDeviceDB.unigMeCount = 0
+ onuDeviceDB.unigMe = make([]*me.ManagedEntity, 4, MaxUnisPerOnu)
+ onuDeviceDB.pptpEthUniMeCount = 0
+ onuDeviceDB.pptpEthUniMe = make([]*me.ManagedEntity, 4, MaxUnisPerOnu)
+ onuDeviceDB.AnigMe = nil
+ onuDeviceDB.VeipMe = nil
+ return &onuDeviceDB
+}
+
+func (onuDeviceDB *OnuDeviceDB) UnigAdd(meParamData me.ParamData) error {
+ var omciErr me.OmciErrors
+ onuDeviceDB.unigMe[onuDeviceDB.unigMeCount], omciErr = me.NewUniG(meParamData)
+ if omciErr.StatusCode() != me.Success {
+ logger.Errorw("UniG could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+ return errors.New("UniG could not be parsed")
+ }
+ logger.Debugw("UniG instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID,
+ "UnigMe ": onuDeviceDB.unigMe[onuDeviceDB.unigMeCount], "unigMeCount": onuDeviceDB.unigMeCount})
+ if onuDeviceDB.unigMeCount < MaxUnisPerOnu {
+ onuDeviceDB.unigMeCount++
+ } else {
+ logger.Errorw("Max number of UniGs exceeded for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+ return errors.New("Max number of UniGs exceeded")
+ }
+ return nil
+}
+
+func (onuDeviceDB *OnuDeviceDB) PptpEthUniAdd(meParamData me.ParamData) error {
+ var omciErr me.OmciErrors
+ onuDeviceDB.pptpEthUniMe[onuDeviceDB.pptpEthUniMeCount], omciErr = me.NewPhysicalPathTerminationPointEthernetUni(meParamData)
+ if omciErr.StatusCode() != me.Success {
+ logger.Errorw("pptpEthUni could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+ return errors.New("pptpEthUni could not be parsed")
+ }
+ logger.Debugw("pptpEthUni instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID,
+ "pptpEthUniMe ": onuDeviceDB.pptpEthUniMe[onuDeviceDB.pptpEthUniMeCount], "pptpEthUniMeCount": onuDeviceDB.pptpEthUniMeCount})
+ if onuDeviceDB.pptpEthUniMeCount < MaxUnisPerOnu {
+ onuDeviceDB.pptpEthUniMeCount++
+ } else {
+ logger.Errorw("Max number of pptpEthUnis exceeded for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+ return errors.New("Max number of pptpEthUnis exceeded")
+ }
+ return nil
+}
+
+func (onuDeviceDB *OnuDeviceDB) AnigAdd(meParamData me.ParamData) error {
+ var omciErr me.OmciErrors
+ onuDeviceDB.AnigMe, omciErr = me.NewAniG(meParamData)
+ if omciErr.StatusCode() != me.Success {
+ logger.Errorw("AniG could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+ return errors.New("AniG could not be parsed")
+ }
+ logger.Debugw("AniG instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "AnigMe ": onuDeviceDB.AnigMe})
+ return nil
+}
+
+func (onuDeviceDB *OnuDeviceDB) VeipAdd(meParamData me.ParamData) error {
+ var omciErr me.OmciErrors
+ onuDeviceDB.VeipMe, omciErr = me.NewVirtualEthernetInterfacePoint(meParamData)
+ if omciErr.StatusCode() != me.Success {
+ logger.Errorw("VEIP could not be parsed for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID})
+ return errors.New("VEIP could not be parsed")
+ }
+ logger.Debugw("VEIP instance stored for:", log.Fields{"deviceId": onuDeviceDB.pOnuDeviceEntry.deviceID, "VeipMe ": onuDeviceDB.VeipMe})
+ return nil
+}
+
+func (onuDeviceDB *OnuDeviceDB) StoreMe(a_pMibUpResp *omci.MibUploadNextResponse) error {
+
+ meParamData := me.ParamData{
+ EntityID: a_pMibUpResp.ReportedME.GetEntityID(),
+ Attributes: a_pMibUpResp.ReportedME.GetAttributeValueMap(),
+ }
+
+ switch a_pMibUpResp.ReportedME.GetClassID() {
+ case me.UniGClassID:
+ onuDeviceDB.UnigAdd(meParamData)
+ case me.PhysicalPathTerminationPointEthernetUniClassID:
+ onuDeviceDB.PptpEthUniAdd(meParamData)
+ case me.AniGClassID:
+ onuDeviceDB.AnigAdd(meParamData)
+ case me.VirtualEthernetInterfacePointClassID:
+ onuDeviceDB.VeipAdd(meParamData)
+ default:
+ //ME won't be stored currently
+ }
+ return nil
+}
diff --git a/internal/pkg/onuadaptercore/onu_device_entry.go b/internal/pkg/onuadaptercore/onu_device_entry.go
index 837dadb..25c7c20 100644
--- a/internal/pkg/onuadaptercore/onu_device_entry.go
+++ b/internal/pkg/onuadaptercore/onu_device_entry.go
@@ -62,6 +62,7 @@
adapterProxy adapterif.AdapterProxy
started bool
PDevOmciCC *OmciCC
+ pOnuDB *OnuDeviceDB
//lockDeviceEntries sync.RWMutex
mibDbClass func() error
supportedFsms OmciDeviceFsms
diff --git a/internal/pkg/onuadaptercore/onu_uni_port.go b/internal/pkg/onuadaptercore/onu_uni_port.go
index adf2b6c..f5fc224 100644
--- a/internal/pkg/onuadaptercore/onu_uni_port.go
+++ b/internal/pkg/onuadaptercore/onu_uni_port.go
@@ -78,7 +78,7 @@
return &onuUniPort
}
-//Start starts (logs) the omci agent
+//creates the Voltha port based on ONU UNI Port
func (oo *OnuUniPort) CreateVolthaPort(a_pDeviceHandler *DeviceHandler) error {
logger.Debug("adding-uni-port")
pUniPort := &voltha.Port{
@@ -105,3 +105,8 @@
}
return nil
}
+
+//mofify OperState of the the UniPort
+func (oo *OnuUniPort) SetOperState(a_NewOperState vc.OperStatus_Types) {
+ oo.operState = a_NewOperState
+}
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
index 81e35d2..1cd7585 100644
--- a/internal/pkg/onuadaptercore/openonu.go
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -167,8 +167,17 @@
//Get_ofp_port_info returns OFP port information for the given device
func (oo *OpenONUAC) Get_ofp_port_info(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
- logger.Errorw("device-handler-not-set", log.Fields{"deviceId": device.Id})
- return nil, errors.New("device-handler-not-set")
+ //this method expects a return value to be sent to the core
+ // and internal processing should not take that long
+ // so it makes no sense to try to work asynchronously here
+ logger.Infow("get-ofp-port-info started", log.Fields{"deviceId": device.Id, "portNo": portNo})
+ // basically the same code as in openOlt.go - unify???
+ if handler := oo.getDeviceHandler(device.Id); handler != nil {
+ return handler.GetOfpPortInfo(device, portNo)
+ // error treatment might be more sophisticated, but indeed it would be logged within handler
+ }
+ return nil, fmt.Errorf(fmt.Sprintf("handler-not-found for deviceId %s", device.Id))
+ //return nil, olterrors.NewErrNotFound("device-handler", log.Fields{"device-id": device.Id}, nil)
}
//Process_inter_adapter_message sends messages to a target device (between adapters)