blob: dff95455a9aa1564614e9e91a1004a000afd48c4 [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000017//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
Holger Hildebrandtfa074992020-03-27 15:42:06 +000019
20import (
21 "context"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000022 "errors"
23
Holger Hildebrandtfa074992020-03-27 15:42:06 +000024 //"sync"
25 //"time"
26
27 "github.com/looplab/fsm"
28 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000029 "github.com/opencord/voltha-lib-go/v3/pkg/db"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000030
31 //"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
32 "github.com/opencord/voltha-lib-go/v3/pkg/log"
33 //ic "github.com/opencord/voltha-protos/v3/go/inter_container"
34 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
35 //"github.com/opencord/voltha-protos/v3/go/voltha"
36)
37
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000038const (
39 KvstoreTimeout = 5 //in seconds
40 BasePathMibTemplateKvStore = "service/voltha/omci_mibs/templates"
41 SuffixMibTemplateKvStore = "%s/%s/%s"
42)
43
Holger Hildebrandtfa074992020-03-27 15:42:06 +000044type OnuDeviceEvent int
45
46const (
47 // Events of interest to Device Adapters and OpenOMCI State Machines
48 DeviceStatusInit OnuDeviceEvent = 0 // OnuDeviceEntry default start state
49 MibDatabaseSync OnuDeviceEvent = 1 // MIB database sync (upload done)
50 OmciCapabilitiesDone OnuDeviceEvent = 2 // OMCI ME and message type capabilities known
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000051 MibDownloadDone OnuDeviceEvent = 3 // MIB database sync (upload done)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000052 UniLockStateDone OnuDeviceEvent = 4 // Uni ports admin set to lock
53 UniUnlockStateDone OnuDeviceEvent = 5 // Uni ports admin set to unlock
54 UniAdminStateDone OnuDeviceEvent = 6 // Uni ports admin set done - general
55 PortLinkUp OnuDeviceEvent = 7 // Port link state change
56 PortLinkDw OnuDeviceEvent = 8 // Port link state change
Holger Hildebrandtfa074992020-03-27 15:42:06 +000057 // Add other events here as needed (alarms separate???)
58)
59
60type activityDescr struct {
61 databaseClass func() error
62 advertiseEvents bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000063 auditDelay uint16
Holger Hildebrandtfa074992020-03-27 15:42:06 +000064 //tasks map[string]func() error
65}
66type OmciDeviceFsms map[string]activityDescr
67
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000068type AdapterFsm struct {
69 fsmName string
70 deviceID string
71 commChan chan Message
72 pFsm *fsm.FSM
73}
74
75func NewAdapterFsm(a_name string, a_deviceID string, a_commChannel chan Message) *AdapterFsm {
76 aFsm := &AdapterFsm{
77 fsmName: a_name,
78 deviceID: a_deviceID,
79 commChan: a_commChannel,
80 }
81 return aFsm
82}
83
84//Start starts (logs) the omci agent
85func (oo *AdapterFsm) logFsmStateChange(e *fsm.Event) {
86 logger.Debugw("FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
87 "event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst)})
88}
89
Holger Hildebrandtfa074992020-03-27 15:42:06 +000090//OntDeviceEntry structure holds information about the attached FSM'as and their communication
91type OnuDeviceEntry struct {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +000092 deviceID string
93 baseDeviceHandler *DeviceHandler
94 coreProxy adapterif.CoreProxy
95 adapterProxy adapterif.AdapterProxy
96 started bool
97 PDevOmciCC *OmciCC
98 pOnuDB *OnuDeviceDB
99 mibTemplateKVStore *db.Backend
100 vendorID string
101 serialNumber string
102 equipmentID string
103 activeSwVersion string
104 macAddress string
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000105 //lockDeviceEntries sync.RWMutex
106 mibDbClass func() error
107 supportedFsms OmciDeviceFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000108 devState OnuDeviceEvent
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000109 // for mibUpload
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000110 mibAuditDelay uint16
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000111
112 // for mibUpload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000113 pMibUploadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
114 // for mibDownload
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000115 pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
116 //remark: general usage of pAdapterFsm would require generalization of commChan usage and internal event setting
117 // within the FSM event procedures
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000118 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000119}
120
121//OnuDeviceEntry returns a new instance of a OnuDeviceEntry
122//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000123func NewOnuDeviceEntry(ctx context.Context, device_id string, kVStoreHost string, kVStorePort int, kvStoreType string, device_Handler *DeviceHandler,
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000124 core_proxy adapterif.CoreProxy, adapter_proxy adapterif.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000125 supported_Fsms_Ptr *OmciDeviceFsms) *OnuDeviceEntry {
126 logger.Infow("init-onuDeviceEntry", log.Fields{"deviceId": device_id})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000127 var onuDeviceEntry OnuDeviceEntry
128 onuDeviceEntry.started = false
129 onuDeviceEntry.deviceID = device_id
130 onuDeviceEntry.baseDeviceHandler = device_Handler
131 onuDeviceEntry.coreProxy = core_proxy
132 onuDeviceEntry.adapterProxy = adapter_proxy
133 onuDeviceEntry.devState = DeviceStatusInit
134 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
135 //OMCI related databases are on a per-agent basis. State machines and tasks
136 //are per ONU Vendor
137 //
138 // MIB Synchronization Database - possible overloading from arguments
139 if supported_Fsms_Ptr != nil {
140 onuDeviceEntry.supportedFsms = *supported_Fsms_Ptr
141 } else {
142 //var mibSyncFsm = NewMibSynchronizer()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000143 // use some internaƶ defaults, if not defined from outside
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000144 onuDeviceEntry.supportedFsms = OmciDeviceFsms{
145 "mib-synchronizer": {
146 //mibSyncFsm, // Implements the MIB synchronization state machine
147 onuDeviceEntry.MibDbVolatileDict, // Implements volatile ME MIB database
148 true, // Advertise events on OpenOMCI event bus
149 60, // Time to wait between MIB audits. 0 to disable audits.
150 // map[string]func() error{
151 // "mib-upload": onuDeviceEntry.MibUploadTask,
152 // "mib-template": onuDeviceEntry.MibTemplateTask,
153 // "get-mds": onuDeviceEntry.GetMdsTask,
154 // "mib-audit": onuDeviceEntry.GetMdsTask,
155 // "mib-resync": onuDeviceEntry.MibResyncTask,
156 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
157 // },
158 },
159 }
160 }
161 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000162 logger.Debug("access2mibDbClass")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000163 go onuDeviceEntry.mibDbClass()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164 onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
165 logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000166
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000167 // Omci related Mib upload sync state machine
168 mibUploadChan := make(chan Message, 2048)
169 onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", device_id, mibUploadChan)
170 onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000171 "disabled",
172 fsm.Events{
173
174 {Name: "start", Src: []string{"disabled"}, Dst: "starting"},
175
176 {Name: "load_mib_template", Src: []string{"starting"}, Dst: "loading_mib_template"},
177 {Name: "upload_mib", Src: []string{"loading_mib_template"}, Dst: "uploading"},
178 {Name: "examine_mds", Src: []string{"starting"}, Dst: "examining_mds"},
179
180 {Name: "success", Src: []string{"loading_mib_template"}, Dst: "in_sync"},
181 {Name: "success", Src: []string{"uploading"}, Dst: "in_sync"},
182
183 {Name: "success", Src: []string{"examining_mds"}, Dst: "in_sync"},
184 {Name: "mismatch", Src: []string{"examining_mds"}, Dst: "resynchronizing"},
185
186 {Name: "audit_mib", Src: []string{"in_sync"}, Dst: "auditing"},
187
188 {Name: "success", Src: []string{"out_of_sync"}, Dst: "in_sync"},
189 {Name: "audit_mib", Src: []string{"out_of_sync"}, Dst: "auditing"},
190
191 {Name: "success", Src: []string{"auditing"}, Dst: "in_sync"},
192 {Name: "mismatch", Src: []string{"auditing"}, Dst: "resynchronizing"},
193 {Name: "force_resync", Src: []string{"auditing"}, Dst: "resynchronizing"},
194
195 {Name: "success", Src: []string{"resynchronizing"}, Dst: "in_sync"},
196 {Name: "diffs_found", Src: []string{"resynchronizing"}, Dst: "out_of_sync"},
197
198 {Name: "timeout", Src: []string{"loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "starting"},
199
200 {Name: "stop", Src: []string{"starting", "loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "disabled"},
201 },
202
203 fsm.Callbacks{
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000204 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibUploadFsm.logFsmStateChange(e) },
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000205 "enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
206 "enter_loading_mib_template": func(e *fsm.Event) { onuDeviceEntry.enterLoadingMibTemplateState(e) },
207 "enter_uploading": func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
208 "enter_examining_mds": func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
209 "enter_resynchronizing": func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
210 "enter_auditing": func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
211 "enter_out_of_sync": func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
212 "enter_in_sync": func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
213 },
214 )
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000215 // Omci related Mib download state machine
216 mibDownloadChan := make(chan Message, 2048)
217 onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", device_id, mibDownloadChan)
218 onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
219 "disabled",
220 fsm.Events{
221
222 {Name: "start", Src: []string{"disabled"}, Dst: "starting"},
223
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000224 {Name: "create_gal", Src: []string{"starting"}, Dst: "creatingGal"},
225 {Name: "rx_gal_resp", Src: []string{"creatingGal"}, Dst: "settingOnu2g"},
226 {Name: "rx_onu2g_resp", Src: []string{"settingOnu2g"}, Dst: "bridgeInit"},
227 // the bridge state is used for multi ME config for alle UNI related ports
228 // maybe such could be reflected in the state machine as well (port number parametrized)
229 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
230 {Name: "rx_bridge_resp", Src: []string{"bridgeInit"}, Dst: "downloaded"},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000231
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000232 {Name: "timeout_simple", Src: []string{"creatingGal", "settingOnu2g"}, Dst: "starting"},
233 {Name: "timeout_bridge", Src: []string{"bridgeInit"}, Dst: "starting"},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000234
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000235 {Name: "reset", Src: []string{"starting", "creatingGal", "settingOnu2g",
236 "bridgeInit", "downloaded"}, Dst: "resetting"},
237 // exceptional treatment for all states except "resetting"
238 {Name: "restart", Src: []string{"starting", "creatingGal", "settingOnu2g",
239 "bridgeInit", "downloaded", "resetting"}, Dst: "disabled"},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000240 },
241
242 fsm.Callbacks{
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000243 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(e) },
244 "enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(e) },
245 "enter_creatingGal": func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(e) },
246 "enter_settingOnu2g": func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(e) },
247 "enter_bridgeInit": func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(e) },
248 "enter_downloaded": func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(e) },
249 "enter_resetting": func(e *fsm.Event) { onuDeviceEntry.enterResettingState(e) },
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000250 },
251 )
252 if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
253 logger.Error("MibDownloadFsm could not be instantiated!!")
254 // some specifc error treatment - or waiting for crash ???
255 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000256
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000257 onuDeviceEntry.mibTemplateKVStore = onuDeviceEntry.SetKVClient(kvStoreType, kVStoreHost, kVStorePort, BasePathMibTemplateKvStore)
258 if onuDeviceEntry.mibTemplateKVStore == nil {
259 logger.Error("Failed to setup mibTemplateKVStore")
260 }
261
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000262 // Alarm Synchronization Database
263 //self._alarm_db = None
264 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
265 return &onuDeviceEntry
266}
267
268//Start starts (logs) the omci agent
269func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 logger.Info("starting-OnuDeviceEntry")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000271
272 oo.PDevOmciCC = NewOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
273 oo.coreProxy, oo.adapterProxy)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000274 if oo.PDevOmciCC == nil {
275 logger.Errorw("Could not create devOmciCc - abort", log.Fields{"for device": oo.deviceID})
276 return errors.New("Could not create devOmciCc")
277 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000278
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000279 oo.started = true
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000280 logger.Info("OnuDeviceEntry-started")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000281 return nil
282}
283
284//Stop terminates the session
285func (oo *OnuDeviceEntry) Stop(ctx context.Context) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 logger.Info("stopping-OnuDeviceEntry")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000287 oo.started = false
288 //oo.exitChannel <- 1
mpagenko3af1f032020-06-10 08:53:41 +0000289 // maybe also the omciCC should be stopped here - for now not as no real processing is expected here - maybe needs consolidation
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290 logger.Info("OnuDeviceEntry-stopped")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000291 return nil
292}
293
294//Relay the InSync message via Handler to Rw core - Status update
295func (oo *OnuDeviceEntry) transferSystemEvent(dev_Event OnuDeviceEvent) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 logger.Debugw("relaying system-event", log.Fields{"Event": dev_Event})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000297 // decouple the handler transfer from further processing here
298 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
299 if dev_Event == MibDatabaseSync {
300 if oo.devState < MibDatabaseSync { //devState has not been synced yet
301 oo.devState = MibDatabaseSync
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000302 go oo.baseDeviceHandler.DeviceProcStatusUpdate(dev_Event)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000303 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
304 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
306 }
307 } else if dev_Event == MibDownloadDone {
308 if oo.devState < MibDownloadDone { //devState has not been synced yet
309 oo.devState = MibDownloadDone
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000310 go oo.baseDeviceHandler.DeviceProcStatusUpdate(dev_Event)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 } else {
312 logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000313 }
314 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 logger.Warnw("device-event not yet handled", log.Fields{"state": dev_Event})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000316 }
317 return nil
318}