blob: 62b86c049fc7a19b23105be2e082d1be7596e86e [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"
22 //"errors"
23 //"sync"
24 //"time"
25
26 "github.com/looplab/fsm"
27 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
28
29 //"github.com/opencord/voltha-lib-go/v3/pkg/kafka"
30 "github.com/opencord/voltha-lib-go/v3/pkg/log"
31 //ic "github.com/opencord/voltha-protos/v3/go/inter_container"
32 //"github.com/opencord/voltha-protos/v3/go/openflow_13"
33 //"github.com/opencord/voltha-protos/v3/go/voltha"
34)
35
36type OnuDeviceEvent int
37
38const (
39 // Events of interest to Device Adapters and OpenOMCI State Machines
40 DeviceStatusInit OnuDeviceEvent = 0 // OnuDeviceEntry default start state
41 MibDatabaseSync OnuDeviceEvent = 1 // MIB database sync (upload done)
42 OmciCapabilitiesDone OnuDeviceEvent = 2 // OMCI ME and message type capabilities known
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000043 MibDownloadDone OnuDeviceEvent = 3 // MIB database sync (upload done)
44 PortLinkUp OnuDeviceEvent = 4 // Port link state change
45 PortLinkDw OnuDeviceEvent = 5 // Port link state change
Holger Hildebrandtfa074992020-03-27 15:42:06 +000046 // Add other events here as needed (alarms separate???)
47)
48
49type activityDescr struct {
50 databaseClass func() error
51 advertiseEvents bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000052 auditDelay uint16
Holger Hildebrandtfa074992020-03-27 15:42:06 +000053 //tasks map[string]func() error
54}
55type OmciDeviceFsms map[string]activityDescr
56
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000057type AdapterFsm struct {
58 fsmName string
59 deviceID string
60 commChan chan Message
61 pFsm *fsm.FSM
62}
63
64func NewAdapterFsm(a_name string, a_deviceID string, a_commChannel chan Message) *AdapterFsm {
65 aFsm := &AdapterFsm{
66 fsmName: a_name,
67 deviceID: a_deviceID,
68 commChan: a_commChannel,
69 }
70 return aFsm
71}
72
73//Start starts (logs) the omci agent
74func (oo *AdapterFsm) logFsmStateChange(e *fsm.Event) {
75 logger.Debugw("FSM state change", log.Fields{"device-id": oo.deviceID, "FSM name": oo.fsmName,
76 "event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst)})
77}
78
Holger Hildebrandtfa074992020-03-27 15:42:06 +000079//OntDeviceEntry structure holds information about the attached FSM'as and their communication
80type OnuDeviceEntry struct {
81 deviceID string
82 baseDeviceHandler *DeviceHandler
83 coreProxy adapterif.CoreProxy
84 adapterProxy adapterif.AdapterProxy
85 started bool
86 PDevOmciCC *OmciCC
Holger Hildebrandt24d51952020-05-04 14:03:42 +000087 pOnuDB *OnuDeviceDB
Holger Hildebrandtfa074992020-03-27 15:42:06 +000088 //lockDeviceEntries sync.RWMutex
89 mibDbClass func() error
90 supportedFsms OmciDeviceFsms
Holger Hildebrandtfa074992020-03-27 15:42:06 +000091 devState OnuDeviceEvent
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000092 // for mibUpload
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000093 mibAuditDelay uint16
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000094 //MibSyncFsm *fsm.FSM
95 //MibSyncChan chan Message
96 pMibUploadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
97 // for mibDownload
98 //MibDownloadFsm *fsm.FSM
99 //MibDownloadChan chan Message
100 pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
101 //remark: general usage of pAdapterFsm would require generalization of commChan usage and internal event setting
102 // within the FSM event procedures
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000103}
104
105//OnuDeviceEntry returns a new instance of a OnuDeviceEntry
106//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
107func NewOnuDeviceEntry(ctx context.Context,
108 device_id string, device_Handler *DeviceHandler,
109 core_proxy adapterif.CoreProxy, adapter_proxy adapterif.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000110 supported_Fsms_Ptr *OmciDeviceFsms) *OnuDeviceEntry {
111 logger.Infow("init-onuDeviceEntry", log.Fields{"deviceId": device_id})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000112 var onuDeviceEntry OnuDeviceEntry
113 onuDeviceEntry.started = false
114 onuDeviceEntry.deviceID = device_id
115 onuDeviceEntry.baseDeviceHandler = device_Handler
116 onuDeviceEntry.coreProxy = core_proxy
117 onuDeviceEntry.adapterProxy = adapter_proxy
118 onuDeviceEntry.devState = DeviceStatusInit
119 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
120 //OMCI related databases are on a per-agent basis. State machines and tasks
121 //are per ONU Vendor
122 //
123 // MIB Synchronization Database - possible overloading from arguments
124 if supported_Fsms_Ptr != nil {
125 onuDeviceEntry.supportedFsms = *supported_Fsms_Ptr
126 } else {
127 //var mibSyncFsm = NewMibSynchronizer()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000128 // use some internaƶ defaults, if not defined from outside
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000129 onuDeviceEntry.supportedFsms = OmciDeviceFsms{
130 "mib-synchronizer": {
131 //mibSyncFsm, // Implements the MIB synchronization state machine
132 onuDeviceEntry.MibDbVolatileDict, // Implements volatile ME MIB database
133 true, // Advertise events on OpenOMCI event bus
134 60, // Time to wait between MIB audits. 0 to disable audits.
135 // map[string]func() error{
136 // "mib-upload": onuDeviceEntry.MibUploadTask,
137 // "mib-template": onuDeviceEntry.MibTemplateTask,
138 // "get-mds": onuDeviceEntry.GetMdsTask,
139 // "mib-audit": onuDeviceEntry.GetMdsTask,
140 // "mib-resync": onuDeviceEntry.MibResyncTask,
141 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
142 // },
143 },
144 }
145 }
146 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000147 logger.Debug("access2mibDbClass")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000148 go onuDeviceEntry.mibDbClass()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000149 onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
150 logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000151
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000152 // Omci related Mib upload sync state machine
153 mibUploadChan := make(chan Message, 2048)
154 onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", device_id, mibUploadChan)
155 onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000156 "disabled",
157 fsm.Events{
158
159 {Name: "start", Src: []string{"disabled"}, Dst: "starting"},
160
161 {Name: "load_mib_template", Src: []string{"starting"}, Dst: "loading_mib_template"},
162 {Name: "upload_mib", Src: []string{"loading_mib_template"}, Dst: "uploading"},
163 {Name: "examine_mds", Src: []string{"starting"}, Dst: "examining_mds"},
164
165 {Name: "success", Src: []string{"loading_mib_template"}, Dst: "in_sync"},
166 {Name: "success", Src: []string{"uploading"}, Dst: "in_sync"},
167
168 {Name: "success", Src: []string{"examining_mds"}, Dst: "in_sync"},
169 {Name: "mismatch", Src: []string{"examining_mds"}, Dst: "resynchronizing"},
170
171 {Name: "audit_mib", Src: []string{"in_sync"}, Dst: "auditing"},
172
173 {Name: "success", Src: []string{"out_of_sync"}, Dst: "in_sync"},
174 {Name: "audit_mib", Src: []string{"out_of_sync"}, Dst: "auditing"},
175
176 {Name: "success", Src: []string{"auditing"}, Dst: "in_sync"},
177 {Name: "mismatch", Src: []string{"auditing"}, Dst: "resynchronizing"},
178 {Name: "force_resync", Src: []string{"auditing"}, Dst: "resynchronizing"},
179
180 {Name: "success", Src: []string{"resynchronizing"}, Dst: "in_sync"},
181 {Name: "diffs_found", Src: []string{"resynchronizing"}, Dst: "out_of_sync"},
182
183 {Name: "timeout", Src: []string{"loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "starting"},
184
185 {Name: "stop", Src: []string{"starting", "loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "disabled"},
186 },
187
188 fsm.Callbacks{
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000189 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(e) },
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000190 "enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
191 "enter_loading_mib_template": func(e *fsm.Event) { onuDeviceEntry.enterLoadingMibTemplateState(e) },
192 "enter_uploading": func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
193 "enter_examining_mds": func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
194 "enter_resynchronizing": func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
195 "enter_auditing": func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
196 "enter_out_of_sync": func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
197 "enter_in_sync": func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
198 },
199 )
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000200 // Omci related Mib download state machine
201 mibDownloadChan := make(chan Message, 2048)
202 onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", device_id, mibDownloadChan)
203 onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
204 "disabled",
205 fsm.Events{
206
207 {Name: "start", Src: []string{"disabled"}, Dst: "starting"},
208
209 {Name: "download_mib", Src: []string{"starting"}, Dst: "downloading"},
210
211 {Name: "success", Src: []string{"downloading"}, Dst: "downloaded"},
212
213 {Name: "timeout", Src: []string{"downloading"}, Dst: "starting"},
214
215 {Name: "restart", Src: []string{"starting", "downloading", "downloaded"}, Dst: "disabled"},
216 },
217
218 fsm.Callbacks{
219 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(e) },
220 "enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(e) },
221 "enter_downloading": func(e *fsm.Event) { onuDeviceEntry.enterDownloadingState(e) },
222 "enter_downloaded": func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(e) },
223 },
224 )
225 if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
226 logger.Error("MibDownloadFsm could not be instantiated!!")
227 // some specifc error treatment - or waiting for crash ???
228 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000229
230 // Alarm Synchronization Database
231 //self._alarm_db = None
232 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
233 return &onuDeviceEntry
234}
235
236//Start starts (logs) the omci agent
237func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 logger.Info("starting-OnuDeviceEntry")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000239
240 oo.PDevOmciCC = NewOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
241 oo.coreProxy, oo.adapterProxy)
242
243 //TODO .....
244 //mib_db.start()
245 oo.started = true
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 logger.Info("OnuDeviceEntry-started, but not yet mib_db!!!")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000247 return nil
248}
249
250//Stop terminates the session
251func (oo *OnuDeviceEntry) Stop(ctx context.Context) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 logger.Info("stopping-OnuDeviceEntry")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000253 oo.started = false
254 //oo.exitChannel <- 1
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 logger.Info("OnuDeviceEntry-stopped")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000256 return nil
257}
258
259//Relay the InSync message via Handler to Rw core - Status update
260func (oo *OnuDeviceEntry) transferSystemEvent(dev_Event OnuDeviceEvent) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 logger.Debugw("relaying system-event", log.Fields{"Event": dev_Event})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000262 // decouple the handler transfer from further processing here
263 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
264 if dev_Event == MibDatabaseSync {
265 if oo.devState < MibDatabaseSync { //devState has not been synced yet
266 oo.devState = MibDatabaseSync
267 go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
268 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
269 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
271 }
272 } else if dev_Event == MibDownloadDone {
273 if oo.devState < MibDownloadDone { //devState has not been synced yet
274 oo.devState = MibDownloadDone
275 go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
276 } else {
277 logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000278 }
279 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000280 logger.Warnw("device-event not yet handled", log.Fields{"state": dev_Event})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000281 }
282 return nil
283}