blob: 837dadb0bcf0492bec929cf82316e2d6eacfab01 [file] [log] [blame]
/*
* 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"
//"sync"
//"time"
"github.com/looplab/fsm"
"github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
//"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
//ic "github.com/opencord/voltha-protos/v3/go/inter_container"
//"github.com/opencord/voltha-protos/v3/go/openflow_13"
//"github.com/opencord/voltha-protos/v3/go/voltha"
)
type OnuDeviceEvent int
const (
// Events of interest to Device Adapters and OpenOMCI State Machines
DeviceStatusInit OnuDeviceEvent = 0 // OnuDeviceEntry default start state
MibDatabaseSync OnuDeviceEvent = 1 // MIB database sync (upload done)
OmciCapabilitiesDone OnuDeviceEvent = 2 // OMCI ME and message type capabilities known
MibDownloadDone OnuDeviceEvent = 3 // MIB database sync (upload done)
PortLinkUp OnuDeviceEvent = 4 // Port link state change
PortLinkDw OnuDeviceEvent = 5 // Port link state change
// Add other events here as needed (alarms separate???)
)
type activityDescr struct {
databaseClass func() error
advertiseEvents bool
auditDelay uint16
//tasks map[string]func() error
}
type OmciDeviceFsms map[string]activityDescr
//OntDeviceEntry structure holds information about the attached FSM'as and their communication
type OnuDeviceEntry struct {
deviceID string
baseDeviceHandler *DeviceHandler
coreProxy adapterif.CoreProxy
adapterProxy adapterif.AdapterProxy
started bool
PDevOmciCC *OmciCC
//lockDeviceEntries sync.RWMutex
mibDbClass func() error
supportedFsms OmciDeviceFsms
MibSyncFsm *fsm.FSM
MibSyncChan chan Message
devState OnuDeviceEvent
mibAuditDelay uint16
}
//OnuDeviceEntry returns a new instance of a OnuDeviceEntry
//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
func NewOnuDeviceEntry(ctx context.Context,
device_id string, device_Handler *DeviceHandler,
core_proxy adapterif.CoreProxy, adapter_proxy adapterif.AdapterProxy,
supported_Fsms_Ptr *OmciDeviceFsms) *OnuDeviceEntry {
logger.Infow("init-onuDeviceEntry", log.Fields{"deviceId": device_id})
var onuDeviceEntry OnuDeviceEntry
onuDeviceEntry.started = false
onuDeviceEntry.deviceID = device_id
onuDeviceEntry.baseDeviceHandler = device_Handler
onuDeviceEntry.coreProxy = core_proxy
onuDeviceEntry.adapterProxy = adapter_proxy
onuDeviceEntry.devState = DeviceStatusInit
//openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
//OMCI related databases are on a per-agent basis. State machines and tasks
//are per ONU Vendor
//
// MIB Synchronization Database - possible overloading from arguments
if supported_Fsms_Ptr != nil {
onuDeviceEntry.supportedFsms = *supported_Fsms_Ptr
} else {
//var mibSyncFsm = NewMibSynchronizer()
// use some internaƶ defaults, if not defined from outside
onuDeviceEntry.supportedFsms = OmciDeviceFsms{
"mib-synchronizer": {
//mibSyncFsm, // Implements the MIB synchronization state machine
onuDeviceEntry.MibDbVolatileDict, // Implements volatile ME MIB database
true, // Advertise events on OpenOMCI event bus
60, // Time to wait between MIB audits. 0 to disable audits.
// map[string]func() error{
// "mib-upload": onuDeviceEntry.MibUploadTask,
// "mib-template": onuDeviceEntry.MibTemplateTask,
// "get-mds": onuDeviceEntry.GetMdsTask,
// "mib-audit": onuDeviceEntry.GetMdsTask,
// "mib-resync": onuDeviceEntry.MibResyncTask,
// "mib-reconcile": onuDeviceEntry.MibReconcileTask,
// },
},
}
}
onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
logger.Debug("access2mibDbClass")
go onuDeviceEntry.mibDbClass()
onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
// Omci related Mib sync state machine
onuDeviceEntry.MibSyncFsm = fsm.NewFSM(
"disabled",
fsm.Events{
{Name: "start", Src: []string{"disabled"}, Dst: "starting"},
{Name: "load_mib_template", Src: []string{"starting"}, Dst: "loading_mib_template"},
{Name: "upload_mib", Src: []string{"loading_mib_template"}, Dst: "uploading"},
{Name: "examine_mds", Src: []string{"starting"}, Dst: "examining_mds"},
{Name: "success", Src: []string{"loading_mib_template"}, Dst: "in_sync"},
{Name: "success", Src: []string{"uploading"}, Dst: "in_sync"},
{Name: "success", Src: []string{"examining_mds"}, Dst: "in_sync"},
{Name: "mismatch", Src: []string{"examining_mds"}, Dst: "resynchronizing"},
{Name: "audit_mib", Src: []string{"in_sync"}, Dst: "auditing"},
{Name: "success", Src: []string{"out_of_sync"}, Dst: "in_sync"},
{Name: "audit_mib", Src: []string{"out_of_sync"}, Dst: "auditing"},
{Name: "success", Src: []string{"auditing"}, Dst: "in_sync"},
{Name: "mismatch", Src: []string{"auditing"}, Dst: "resynchronizing"},
{Name: "force_resync", Src: []string{"auditing"}, Dst: "resynchronizing"},
{Name: "success", Src: []string{"resynchronizing"}, Dst: "in_sync"},
{Name: "diffs_found", Src: []string{"resynchronizing"}, Dst: "out_of_sync"},
{Name: "timeout", Src: []string{"loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "starting"},
{Name: "stop", Src: []string{"starting", "loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "disabled"},
},
fsm.Callbacks{
"enter_state": func(e *fsm.Event) { onuDeviceEntry.logStateChange(e) },
"enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
"enter_loading_mib_template": func(e *fsm.Event) { onuDeviceEntry.enterLoadingMibTemplateState(e) },
"enter_uploading": func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
"enter_examining_mds": func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
"enter_resynchronizing": func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
"enter_auditing": func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
"enter_out_of_sync": func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
"enter_in_sync": func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
},
)
// Alarm Synchronization Database
//self._alarm_db = None
//self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
return &onuDeviceEntry
}
//Start starts (logs) the omci agent
func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
logger.Info("starting-OnuDeviceEntry")
oo.PDevOmciCC = NewOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
oo.coreProxy, oo.adapterProxy)
//TODO .....
//mib_db.start()
oo.started = true
logger.Info("OnuDeviceEntry-started, but not yet mib_db!!!")
return nil
}
//Stop terminates the session
func (oo *OnuDeviceEntry) Stop(ctx context.Context) error {
logger.Info("stopping-OnuDeviceEntry")
oo.started = false
//oo.exitChannel <- 1
logger.Info("OnuDeviceEntry-stopped")
return nil
}
//Relay the InSync message via Handler to Rw core - Status update
func (oo *OnuDeviceEntry) transferSystemEvent(dev_Event OnuDeviceEvent) error {
logger.Debugw("relaying system-event", log.Fields{"Event": dev_Event})
// decouple the handler transfer from further processing here
// TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
if dev_Event == MibDatabaseSync {
if oo.devState < MibDatabaseSync { //devState has not been synced yet
oo.devState = MibDatabaseSync
go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
//TODO!!! device control: next step: start MIB capability verification from here ?!!!
} else {
logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
}
} else if dev_Event == MibDownloadDone {
if oo.devState < MibDownloadDone { //devState has not been synced yet
oo.devState = MibDownloadDone
go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
} else {
logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
}
} else {
logger.Warnw("device-event not yet handled", log.Fields{"state": dev_Event})
}
return nil
}