[VOL-3188] - concurrency protection enhancement to ensure setup for muliple ONU parallel start
[VOL-3167] - Implementd device handler processing based on ONU-Indication-Request OperStatus Unreachable/Down
Change-Id: Ia4fd92111c9e49fc174c791aafb4ee00305043a9
Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
diff --git a/VERSION b/VERSION
index 4b88d86..588933b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.11-dev115
+0.1.11-dev118
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index b67ceab..44a5b6a 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -88,10 +88,12 @@
pOpenOnuAc *OpenONUAC
pDeviceStateFsm *fsm.FSM
pPonPort *voltha.Port
+ deviceEntrySet chan bool //channel for DeviceEntry set event
pOnuOmciDevice *OnuDeviceEntry
exitChannel chan int
lockDevice sync.RWMutex
pOnuIndication *oop.OnuIndication
+ deviceReason string
pLockStateFsm *LockStateFsm
pUnlockStateFsm *LockStateFsm
@@ -123,6 +125,7 @@
dh.pOpenOnuAc = adapter
dh.exitChannel = make(chan int, 1)
dh.lockDevice = sync.RWMutex{}
+ dh.deviceEntrySet = make(chan bool, 1)
dh.stopCollector = make(chan bool, 2)
dh.stopHeartbeatCheck = make(chan bool, 2)
//dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
@@ -223,7 +226,13 @@
logger.Debugw("inter-adapter-recv-omci",
log.Fields{"RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
//receive_message(omci_msg.message)
- return dh.GetOnuDeviceEntry().PDevOmciCC.ReceiveMessage(context.TODO(), omciMsg.Message)
+ pDevEntry := dh.GetOnuDeviceEntry(true)
+ if pDevEntry != nil {
+ return pDevEntry.PDevOmciCC.ReceiveMessage(context.TODO(), omciMsg.Message)
+ } else {
+ logger.Errorw("No valid OnuDevice -aborting", log.Fields{"deviceID": dh.deviceID})
+ return errors.New("No valid OnuDevice")
+ }
}
case ic.InterAdapterMessageType_ONU_IND_REQUEST:
{
@@ -239,11 +248,11 @@
"AdminState": onu_indication.GetAdminState(), "OperState": onu_operstate,
"SNR": onu_indication.GetSerialNumber()})
- //interface related functioons might be error checked ....
+ //interface related functions might be error checked ....
if onu_operstate == "up" {
dh.create_interface(onu_indication)
} else if (onu_operstate == "down") || (onu_operstate == "unreachable") {
- dh.update_interface(onu_indication)
+ dh.updateInterface(onu_indication)
} else {
logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onu_indication.GetOnuId()})
return errors.New("InvalidOperState")
@@ -288,41 +297,53 @@
}
//DisableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
+// TODO!!! Clarify usage of this method, it is for sure not used within ONOS (OLT) device disable
+// maybe it is obsolete by now
func (dh *DeviceHandler) DisableDevice(device *voltha.Device) {
logger.Debugw("disable-device", log.Fields{"DeviceId": device.Id, "SerialNumber": device.SerialNumber})
- // disable UNI ports/ONU
- // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
- // here the result of the processing is not checked (trusted in background) *****
- if dh.pLockStateFsm == nil {
- dh.createUniLockFsm(true, UniAdminStateDone)
- } else { //LockStateFSM already init
- dh.pLockStateFsm.SetSuccessEvent(UniAdminStateDone)
- dh.runUniLockFsm(true)
- }
+ //admin-lock reason can also be used uniquely for setting the DeviceState accordingly - inblock
+ //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
+ if dh.deviceReason != "omci-admin-lock" {
+ // disable UNI ports/ONU
+ // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
+ // here the result of the processing is not checked (trusted in background) *****
+ if dh.pLockStateFsm == nil {
+ dh.createUniLockFsm(true, UniAdminStateDone)
+ } else { //LockStateFSM already init
+ dh.pLockStateFsm.SetSuccessEvent(UniAdminStateDone)
+ dh.runUniLockFsm(true)
+ }
- if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
- logger.Errorw("error-updating-reason-state", log.Fields{"deviceID": dh.deviceID, "error": err})
- }
- // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...
- if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
- voltha.OperStatus_UNKNOWN); err != nil {
- logger.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.deviceID, "error": err})
+ if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
+ logger.Errorw("error-updating-reason-state", log.Fields{"deviceID": dh.deviceID, "error": err})
+ }
+ dh.deviceReason = "omci-admin-lock"
+ //200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
+ if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
+ voltha.OperStatus_UNKNOWN); err != nil {
+ logger.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.deviceID, "error": err})
+ }
}
}
//ReenableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
+// TODO!!! Clarify usage of this method, compare above DisableDevice, usage may clarify resulting states
+// maybe it is obsolete by now
func (dh *DeviceHandler) ReenableDevice(device *voltha.Device) {
logger.Debugw("reenable-device", log.Fields{"DeviceId": device.Id, "SerialNumber": device.SerialNumber})
- // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...
+
+ // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...(like python code)
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})
}
+ // TODO!!! DeviceReason to be set here could be more accurate, for now just ...(like python code)
if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
logger.Errorw("error-updating-reason-state", log.Fields{"deviceID": dh.deviceID, "error": err})
}
+ dh.deviceReason = "initial-mib-downloaded"
// enable ONU/UNI ports
// *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
@@ -330,11 +351,12 @@
if dh.pUnlockStateFsm == nil {
dh.createUniLockFsm(false, UniAdminStateDone)
} else { //UnlockStateFSM already init
- dh.pLockStateFsm.SetSuccessEvent(UniAdminStateDone)
+ dh.pUnlockStateFsm.SetSuccessEvent(UniAdminStateDone)
dh.runUniLockFsm(false)
}
}
+//GetOfpPortInfo returns the Voltha PortCapabilty with the logical port
func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device,
portNo int64) (*ic.PortCapability, error) {
logger.Debugw("GetOfpPortInfo start", log.Fields{"deviceID": device.Id, "portNo": portNo})
@@ -403,6 +425,7 @@
dh.device.Vendor = "OpenONU"
dh.device.Model = "go"
dh.device.Reason = "activating-onu"
+ dh.deviceReason = "activating-onu"
dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
@@ -458,8 +481,8 @@
dh.pTransitionMap.Handle(ctx, GrpcConnected)
return nil
*/
- if err = dh.Add_OnuDeviceEntry(context.TODO()); err != nil {
- logger.Fatalf("Device FSM: Add_OnuDeviceEntry-failed-%s", err)
+ if err = dh.AddOnuDeviceEntry(context.TODO()); err != nil {
+ logger.Fatalf("Device FSM: AddOnuDeviceEntry-failed-%s", err)
e.Cancel(err)
return
}
@@ -615,21 +638,31 @@
// ###################################################
// DeviceHandler utility methods ##### begin #########
-// Get ONU device entry for this deviceId specific handler
-func (dh *DeviceHandler) GetOnuDeviceEntry() *OnuDeviceEntry {
- dh.lockDevice.Lock()
- defer dh.lockDevice.Unlock()
- if dh.pOnuOmciDevice != nil {
- logger.Debugw("GetOnuDeviceEntry params:",
- log.Fields{"onu_device_entry": dh.pOnuOmciDevice, "device_id": dh.pOnuOmciDevice.deviceID,
- "device_handler": dh.pOnuOmciDevice.baseDeviceHandler, "core_proxy": dh.pOnuOmciDevice.coreProxy, "adapter_proxy": dh.pOnuOmciDevice.adapterProxy})
- } else {
- logger.Error("GetOnuDeviceEntry returns nil")
+//GetOnuDeviceEntry getsthe ONU device entry and may wait until its value is defined
+func (dh *DeviceHandler) GetOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
+ dh.lockDevice.RLock()
+ pOnuDeviceEntry := dh.pOnuOmciDevice
+ if aWait && pOnuDeviceEntry == nil {
+ //keep the read sema short to allow for subsequent write
+ dh.lockDevice.RUnlock()
+ logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"deviceID": dh.deviceID})
+ // based on concurrent processing the deviceEntry setup may not yet be finished at his point
+ // so it might be needed to wait here for that event with some timeout
+ select {
+ case <-time.After(60 * time.Second): //timer may be discussed ...
+ logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"deviceID": dh.deviceID})
+ return nil
+ case <-dh.deviceEntrySet:
+ logger.Debugw("devicEntry ready now - continue", log.Fields{"deviceID": dh.deviceID})
+ // if written now, we can return the written value without sema
+ return dh.pOnuOmciDevice
+ }
}
- return dh.pOnuOmciDevice
+ dh.lockDevice.RUnlock()
+ return pOnuDeviceEntry
}
-// Set ONU device entry
+//SetOnuDeviceEntry sets the ONU device entry within the handler
func (dh *DeviceHandler) SetOnuDeviceEntry(pDeviceEntry *OnuDeviceEntry) error {
dh.lockDevice.Lock()
defer dh.lockDevice.Unlock()
@@ -637,11 +670,11 @@
return nil
}
-//creates a new ONU device or returns the existing
-func (dh *DeviceHandler) Add_OnuDeviceEntry(ctx context.Context) error {
+//AddOnuDeviceEntry creates a new ONU device or returns the existing
+func (dh *DeviceHandler) AddOnuDeviceEntry(ctx context.Context) error {
logger.Debugw("adding-deviceEntry", log.Fields{"for deviceId": dh.deviceID})
- deviceEntry := dh.GetOnuDeviceEntry()
+ deviceEntry := dh.GetOnuDeviceEntry(false)
if deviceEntry == nil {
/* costum_me_map in python code seems always to be None,
we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
@@ -652,6 +685,8 @@
dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
//error treatment possible //TODO!!!
dh.SetOnuDeviceEntry(deviceEntry)
+ // fire deviceEntry ready event to spread to possibly waiting processing
+ dh.deviceEntrySet <- true
logger.Infow("onuDeviceEntry-added", log.Fields{"for deviceId": dh.deviceID})
} else {
logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"for deviceId": dh.deviceID})
@@ -667,10 +702,10 @@
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 {
+ 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})
}
-
// 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
@@ -685,15 +720,22 @@
}
*/
- dh.GetOnuDeviceEntry().Start(context.TODO())
+ pDevEntry := dh.GetOnuDeviceEntry(true)
+ if pDevEntry != nil {
+ pDevEntry.Start(context.TODO())
+ } else {
+ logger.Errorw("No valid OnuDevice -aborting", log.Fields{"deviceID": dh.deviceID})
+ return errors.New("No valid OnuDevice")
+ }
if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"deviceID": dh.deviceID, "error": err})
}
+ dh.deviceReason = "starting-openomci"
/* this might be a good time for Omci Verify message? */
verifyExec := make(chan bool)
omci_verify := NewOmciTestRequest(context.TODO(),
- dh.device.Id, dh.GetOnuDeviceEntry().PDevOmciCC,
+ dh.device.Id, pDevEntry.PDevOmciCC,
true, true) //eclusive and allowFailure (anyway not yet checked)
omci_verify.PerformOmciTest(context.TODO(), verifyExec)
@@ -781,7 +823,7 @@
//self._heartbeat.enabled = True
//call MibUploadFSM - transition up to state "in_sync"
- pMibUlFsm := dh.GetOnuDeviceEntry().pMibUploadFsm.pFsm
+ pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
if pMibUlFsm != nil {
if pMibUlFsm.Is("disabled") {
if err := pMibUlFsm.Event("start"); err != nil {
@@ -812,15 +854,90 @@
}
} else {
logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"deviceID": dh.deviceID})
+ return errors.New("cannot execut MibSync")
}
return nil
}
-func (dh *DeviceHandler) update_interface(onuind *oop.OnuIndication) error {
- logger.Debug("update_interface-started - not yet implemented")
+func (dh *DeviceHandler) updateInterface(onuind *oop.OnuIndication) error {
+ //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
+ if dh.deviceReason != "stopping-openomci" {
+ logger.Debugw("updateInterface-started - stopping-device", log.Fields{"deviceID": dh.deviceID})
+ //stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
+ pDevEntry := dh.GetOnuDeviceEntry(false)
+ if pDevEntry == nil {
+ logger.Errorw("No valid OnuDevice -aborting", log.Fields{"deviceID": dh.deviceID})
+ return errors.New("No valid OnuDevice")
+ }
+
+ switch dh.deviceReason {
+ case "starting-openomci":
+ { //MIBSync FSM may run
+ pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
+ if pMibUlFsm != nil {
+ pMibUlFsm.Event("stop") //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
+ }
+ }
+ case "discovery-mibsync-complete":
+ { //MibDownload may run
+ pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
+ if pMibDlFsm != nil {
+ pMibDlFsm.Event("reset")
+ }
+ }
+ default:
+ { //port lock/unlock FSM's may be active
+ if dh.pUnlockStateFsm != nil {
+ dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event("reset")
+ }
+ if dh.pLockStateFsm != nil {
+ dh.pLockStateFsm.pAdaptFsm.pFsm.Event("reset")
+ }
+ }
+ //TODO!!! care about PM/Alarm processing once started
+ }
+ //TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
+ // (mainly the still seperate 'Event states')
+ // so it is questionable, how this is resolved after some possible re-enable
+ // assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
+
+ //stop/remove(?) the device entry
+ pDevEntry.Stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
+
+ //TODO!!! remove existing traffic profiles
+ /* from py code, if TP's exist, remove them - not yet implemented
+ self._tp = dict()
+ # Let TP download happen again
+ for uni_id in self._tp_service_specific_task:
+ self._tp_service_specific_task[uni_id].clear()
+ for uni_id in self._tech_profile_download_done:
+ self._tech_profile_download_done[uni_id].clear()
+ */
+
+ dh.disableUniPortStateUpdate()
+
+ if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
+ logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
+ log.Fields{"deviceID": dh.deviceID, "error": err})
+ // abort: system behavior is just unstable ...
+ return err
+ }
+ dh.deviceReason = "stopping-openomci"
+
+ if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
+ voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
+ logger.Errorw("error-updating-device-state unreachable-discovered",
+ log.Fields{"deviceID": dh.deviceID, "error": err})
+ // abort: system behavior is just unstable ...
+ return err
+ }
+ } else {
+ logger.Debugw("updateInterface - device already stopped", log.Fields{"deviceID": dh.deviceID})
+ }
return nil
}
+//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
func (dh *DeviceHandler) DeviceProcStatusUpdate(dev_Event OnuDeviceEvent) {
switch dev_Event {
case MibDatabaseSync:
@@ -831,9 +948,11 @@
logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
"deviceID": dh.deviceID, "error": err})
}
+ dh.deviceReason = "discovery-mibsync-complete"
- unigMap, ok := dh.GetOnuDeviceEntry().pOnuDB.meDb[me.UniGClassID]
- unigInstKeys := dh.GetOnuDeviceEntry().pOnuDB.GetSortedInstKeys(unigMap)
+ pDevEntry := dh.GetOnuDeviceEntry(false)
+ unigMap, ok := pDevEntry.pOnuDB.meDb[me.UniGClassID]
+ unigInstKeys := pDevEntry.pOnuDB.GetSortedInstKeys(unigMap)
i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
if ok {
for _, mgmtEntityId := range unigInstKeys {
@@ -845,8 +964,8 @@
} else {
logger.Debugw("No UniG instances found", log.Fields{"deviceId": dh.deviceID})
}
- veipMap, ok := dh.GetOnuDeviceEntry().pOnuDB.meDb[me.VirtualEthernetInterfacePointClassID]
- veipInstKeys := dh.GetOnuDeviceEntry().pOnuDB.GetSortedInstKeys(veipMap)
+ veipMap, ok := pDevEntry.pOnuDB.meDb[me.VirtualEthernetInterfacePointClassID]
+ veipInstKeys := pDevEntry.pOnuDB.GetSortedInstKeys(veipMap)
if ok {
for _, mgmtEntityId := range veipInstKeys {
logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
@@ -861,23 +980,27 @@
logger.Warnw("No PPTP instances found", log.Fields{"deviceId": dh.deviceID})
}
- // Init Uni Ports to Admin locked state
- // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
- // *** should generate UniLockStateDone event *****
- if dh.pLockStateFsm == nil {
- dh.createUniLockFsm(true, UniLockStateDone)
- } else { //LockStateFSM already init
- dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
- dh.runUniLockFsm(true)
- }
- }
- case UniLockStateDone:
- {
- logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"deviceID": dh.deviceID})
+ /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
+ * left the code here as comment in case such processing should prove needed unexpectedly
+ // Init Uni Ports to Admin locked state
+ // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
+ // *** should generate UniLockStateDone event *****
+ if dh.pLockStateFsm == nil {
+ dh.createUniLockFsm(true, UniLockStateDone)
+ } else { //LockStateFSM already init
+ dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
+ dh.runUniLockFsm(true)
+ }
+ }
+ case UniLockStateDone:
+ {
+ logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"deviceID": dh.deviceID})
+ * lockState processing commented out
+ */
/* Mib download procedure -
***** should run over 'downloaded' state and generate MibDownloadDone event *****
*/
- pMibDlFsm := dh.GetOnuDeviceEntry().pMibDownloadFsm.pFsm
+ pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
if pMibDlFsm != nil {
if pMibDlFsm.Is("disabled") {
if err := pMibDlFsm.Event("start"); err != nil {
@@ -910,11 +1033,13 @@
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 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})
}
+ dh.deviceReason = "initial-mib-downloaded"
// *** should generate UniUnlockStateDone event *****
if dh.pUnlockStateFsm == nil {
@@ -926,7 +1051,7 @@
}
case UniUnlockStateDone:
{
- go dh.enableUniPortStateUpdate(dh.deviceID) //cmp python yield self.enable_ports()
+ go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"deviceID": dh.deviceID})
raisedTs := time.Now().UnixNano()
@@ -961,8 +1086,8 @@
}
}
-// Enable listen on UniPortState changes and update core port state accordingly
-func (dh *DeviceHandler) enableUniPortStateUpdate(a_deviceID string) {
+// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
+func (dh *DeviceHandler) enableUniPortStateUpdate() {
// py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
// but towards core only the first port active state is signalled
// with following remark:
@@ -972,12 +1097,27 @@
// lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
for uniNo, uniPort := range dh.uniEntityMap {
- // only if this port is validated for operState transfer}
+ // only if this port is validated for operState transfer
if (1<<uniPort.uniId)&ActiveUniPortStateUpdateMask == (1 << uniPort.uniId) {
logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
uniPort.SetOperState(vc.OperStatus_ACTIVE)
//maybe also use getter functions on uniPort - perhaps later ...
- go dh.coreProxy.PortStateUpdate(context.TODO(), a_deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
+ go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
+ }
+ }
+}
+
+// Disable UniPortState and update core port state accordingly
+func (dh *DeviceHandler) disableUniPortStateUpdate() {
+ // compare enableUniPortStateUpdate() above
+ // -> use current restriction to operate only on first UNI port as inherited from actual Py code
+ for uniNo, uniPort := range dh.uniEntityMap {
+ // only if this port is validated for operState transfer
+ if (1<<uniPort.uniId)&ActiveUniPortStateUpdateMask == (1 << uniPort.uniId) {
+ logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
+ uniPort.SetOperState(vc.OperStatus_UNKNOWN)
+ //maybe also use getter functions on uniPort - perhaps later ...
+ go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
}
}
}
@@ -1037,7 +1177,13 @@
logger.Infow("createUnlockStateFSM", log.Fields{"deviceID": dh.deviceID})
sFsmName = "UnLockStateFSM"
}
- pLSFsm := NewLockStateFsm(dh.GetOnuDeviceEntry().PDevOmciCC, aAdminState, devEvent,
+
+ pDevEntry := dh.GetOnuDeviceEntry(true)
+ if pDevEntry == nil {
+ logger.Errorw("No valid OnuDevice -aborting", log.Fields{"deviceID": dh.deviceID})
+ return
+ }
+ pLSFsm := NewLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
sFsmName, dh.deviceID, chLSFsm)
if pLSFsm != nil {
if aAdminState == true {
diff --git a/internal/pkg/onuadaptercore/mib_download.go b/internal/pkg/onuadaptercore/mib_download.go
index 8d00188..b6af09b 100644
--- a/internal/pkg/onuadaptercore/mib_download.go
+++ b/internal/pkg/onuadaptercore/mib_download.go
@@ -245,7 +245,7 @@
context.TODO(), uniPort, ConstDefaultOmciTimeout, true)
onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
//verify response
- err := onuDeviceEntry.WaitforOmciResponse(meInstance)
+ err := onuDeviceEntry.waitforOmciResponse(meInstance)
if err != nil {
logger.Error("InitialBridgeSetup failed at MBSP, aborting MIB Download!")
onuDeviceEntry.pMibDownloadFsm.pFsm.Event("reset")
@@ -257,7 +257,7 @@
context.TODO(), uniPort, ConstDefaultOmciTimeout, true)
onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
//verify response
- err = onuDeviceEntry.WaitforOmciResponse(meInstance)
+ err = onuDeviceEntry.waitforOmciResponse(meInstance)
if err != nil {
logger.Error("InitialBridgeSetup failed at MBPCD, aborting MIB Download!")
onuDeviceEntry.pMibDownloadFsm.pFsm.Event("reset")
@@ -269,7 +269,7 @@
context.TODO(), uniPort, ConstDefaultOmciTimeout, true)
onuDeviceEntry.PDevOmciCC.pLastTxMeInstance = meInstance
//verify response
- err = onuDeviceEntry.WaitforOmciResponse(meInstance)
+ err = onuDeviceEntry.waitforOmciResponse(meInstance)
if err != nil {
logger.Error("InitialBridgeSetup failed at EVTOCD, aborting MIB Download!")
onuDeviceEntry.pMibDownloadFsm.pFsm.Event("reset")
@@ -283,12 +283,12 @@
return
}
-func (onuDeviceEntry *OnuDeviceEntry) WaitforOmciResponse(a_pMeInstance *me.ManagedEntity) error {
+func (onuDeviceEntry *OnuDeviceEntry) waitforOmciResponse(apMeInstance *me.ManagedEntity) error {
select {
// maybe be also some outside cancel (but no context modelled for the moment ...)
// case <-ctx.Done():
// logger.Info("MibDownload-bridge-init message reception canceled", log.Fields{"for device-id": onuDeviceEntry.deviceID})
- case <-time.After(3 * time.Second):
+ case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
logger.Warnw("MibDownload-bridge-init timeout", log.Fields{"for device-id": onuDeviceEntry.deviceID})
return errors.New("MibDownloadBridgeInit timeout")
case success := <-onuDeviceEntry.omciMessageReceived:
diff --git a/internal/pkg/onuadaptercore/mib_sync.go b/internal/pkg/onuadaptercore/mib_sync.go
index d5f2696..807412d 100644
--- a/internal/pkg/onuadaptercore/mib_sync.go
+++ b/internal/pkg/onuadaptercore/mib_sync.go
@@ -23,6 +23,7 @@
"errors"
"fmt"
"strconv"
+ "strings"
"github.com/looplab/fsm"
@@ -95,7 +96,13 @@
if err == nil {
if Value != nil {
logger.Debugf("MibSync FSM - MibTemplate read: Key: %s, Value: %s %s", Value.Key, Value.Value)
- mibTmpBytes, _ := kvstore.ToByte(Value.Value)
+
+ // swap out tokens with specific data
+ mibTmpString, _ := kvstore.ToString(Value.Value)
+ mibTmpString2 := strings.Replace(mibTmpString, "%SERIAL_NUMBER%", onuDeviceEntry.serialNumber, -1)
+ mibTmpString = strings.Replace(mibTmpString2, "%MAC_ADDRESS%", onuDeviceEntry.macAddress, -1)
+ mibTmpBytes := []byte(mibTmpString)
+ logger.Debugf("MibSync FSM - MibTemplate tokens swapped out: %s", mibTmpBytes)
var fistLevelMap map[string]interface{}
if err = json.Unmarshal(mibTmpBytes, &fistLevelMap); err != nil {
diff --git a/internal/pkg/onuadaptercore/onu_device_entry.go b/internal/pkg/onuadaptercore/onu_device_entry.go
index 2a7c29e..dff9545 100644
--- a/internal/pkg/onuadaptercore/onu_device_entry.go
+++ b/internal/pkg/onuadaptercore/onu_device_entry.go
@@ -286,6 +286,7 @@
logger.Info("stopping-OnuDeviceEntry")
oo.started = false
//oo.exitChannel <- 1
+ // maybe also the omciCC should be stopped here - for now not as no real processing is expected here - maybe needs consolidation
logger.Info("OnuDeviceEntry-stopped")
return nil
}
diff --git a/internal/pkg/onuadaptercore/uniportadmin.go b/internal/pkg/onuadaptercore/uniportadmin.go
index f7b98da..ed30b41 100644
--- a/internal/pkg/onuadaptercore/uniportadmin.go
+++ b/internal/pkg/onuadaptercore/uniportadmin.go
@@ -340,7 +340,7 @@
}
//verify response
- err := oFsm.WaitforOmciResponse(meInstance)
+ err := oFsm.waitforOmciResponse(meInstance)
if err != nil {
logger.Errorw("PPTP Admin State set failed, aborting LockState set!",
log.Fields{"deviceId": oFsm.pAdaptFsm.deviceID, "Port": uniNo})
@@ -355,12 +355,12 @@
return
}
-func (oFsm *LockStateFsm) WaitforOmciResponse(a_pMeInstance *me.ManagedEntity) error {
+func (oFsm *LockStateFsm) waitforOmciResponse(apMeInstance *me.ManagedEntity) error {
select {
// maybe be also some outside cancel (but no context modelled for the moment ...)
// case <-ctx.Done():
// logger.Infow("LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
- case <-time.After(3 * time.Second):
+ case <-time.After(30 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
logger.Warnw("LockStateFSM uni-set timeout", log.Fields{"for device-id": oFsm.pAdaptFsm.deviceID})
return errors.New("LockStateFsm uni-set timeout")
case success := <-oFsm.omciLockResponseReceived: