blob: 2d7caa6baece329d8864a1f9a095fa435e4d028f [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 Hildebrandtdd23cc22020-05-19 13:32:18 +0000103 omciMessageReceived chan bool //seperate channel needed by DownloadFsm
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000104}
105
106//OnuDeviceEntry returns a new instance of a OnuDeviceEntry
107//mib_db (as well as not inluded alarm_db not really used in this code? VERIFY!!)
108func NewOnuDeviceEntry(ctx context.Context,
109 device_id string, device_Handler *DeviceHandler,
110 core_proxy adapterif.CoreProxy, adapter_proxy adapterif.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000111 supported_Fsms_Ptr *OmciDeviceFsms) *OnuDeviceEntry {
112 logger.Infow("init-onuDeviceEntry", log.Fields{"deviceId": device_id})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000113 var onuDeviceEntry OnuDeviceEntry
114 onuDeviceEntry.started = false
115 onuDeviceEntry.deviceID = device_id
116 onuDeviceEntry.baseDeviceHandler = device_Handler
117 onuDeviceEntry.coreProxy = core_proxy
118 onuDeviceEntry.adapterProxy = adapter_proxy
119 onuDeviceEntry.devState = DeviceStatusInit
120 //openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
121 //OMCI related databases are on a per-agent basis. State machines and tasks
122 //are per ONU Vendor
123 //
124 // MIB Synchronization Database - possible overloading from arguments
125 if supported_Fsms_Ptr != nil {
126 onuDeviceEntry.supportedFsms = *supported_Fsms_Ptr
127 } else {
128 //var mibSyncFsm = NewMibSynchronizer()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000129 // use some internaƶ defaults, if not defined from outside
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000130 onuDeviceEntry.supportedFsms = OmciDeviceFsms{
131 "mib-synchronizer": {
132 //mibSyncFsm, // Implements the MIB synchronization state machine
133 onuDeviceEntry.MibDbVolatileDict, // Implements volatile ME MIB database
134 true, // Advertise events on OpenOMCI event bus
135 60, // Time to wait between MIB audits. 0 to disable audits.
136 // map[string]func() error{
137 // "mib-upload": onuDeviceEntry.MibUploadTask,
138 // "mib-template": onuDeviceEntry.MibTemplateTask,
139 // "get-mds": onuDeviceEntry.GetMdsTask,
140 // "mib-audit": onuDeviceEntry.GetMdsTask,
141 // "mib-resync": onuDeviceEntry.MibResyncTask,
142 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
143 // },
144 },
145 }
146 }
147 onuDeviceEntry.mibDbClass = onuDeviceEntry.supportedFsms["mib-synchronizer"].databaseClass
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000148 logger.Debug("access2mibDbClass")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000149 go onuDeviceEntry.mibDbClass()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000150 onuDeviceEntry.mibAuditDelay = onuDeviceEntry.supportedFsms["mib-synchronizer"].auditDelay
151 logger.Debugw("MibAudit is set to", log.Fields{"Delay": onuDeviceEntry.mibAuditDelay})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000152
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000153 // Omci related Mib upload sync state machine
154 mibUploadChan := make(chan Message, 2048)
155 onuDeviceEntry.pMibUploadFsm = NewAdapterFsm("MibUpload", device_id, mibUploadChan)
156 onuDeviceEntry.pMibUploadFsm.pFsm = fsm.NewFSM(
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000157 "disabled",
158 fsm.Events{
159
160 {Name: "start", Src: []string{"disabled"}, Dst: "starting"},
161
162 {Name: "load_mib_template", Src: []string{"starting"}, Dst: "loading_mib_template"},
163 {Name: "upload_mib", Src: []string{"loading_mib_template"}, Dst: "uploading"},
164 {Name: "examine_mds", Src: []string{"starting"}, Dst: "examining_mds"},
165
166 {Name: "success", Src: []string{"loading_mib_template"}, Dst: "in_sync"},
167 {Name: "success", Src: []string{"uploading"}, Dst: "in_sync"},
168
169 {Name: "success", Src: []string{"examining_mds"}, Dst: "in_sync"},
170 {Name: "mismatch", Src: []string{"examining_mds"}, Dst: "resynchronizing"},
171
172 {Name: "audit_mib", Src: []string{"in_sync"}, Dst: "auditing"},
173
174 {Name: "success", Src: []string{"out_of_sync"}, Dst: "in_sync"},
175 {Name: "audit_mib", Src: []string{"out_of_sync"}, Dst: "auditing"},
176
177 {Name: "success", Src: []string{"auditing"}, Dst: "in_sync"},
178 {Name: "mismatch", Src: []string{"auditing"}, Dst: "resynchronizing"},
179 {Name: "force_resync", Src: []string{"auditing"}, Dst: "resynchronizing"},
180
181 {Name: "success", Src: []string{"resynchronizing"}, Dst: "in_sync"},
182 {Name: "diffs_found", Src: []string{"resynchronizing"}, Dst: "out_of_sync"},
183
184 {Name: "timeout", Src: []string{"loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "starting"},
185
186 {Name: "stop", Src: []string{"starting", "loading_mib_template", "uploading", "resynchronizing", "examining_mds", "in_sync", "out_of_sync", "auditing"}, Dst: "disabled"},
187 },
188
189 fsm.Callbacks{
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000190 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibUploadFsm.logFsmStateChange(e) },
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000191 "enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterStartingState(e) },
192 "enter_loading_mib_template": func(e *fsm.Event) { onuDeviceEntry.enterLoadingMibTemplateState(e) },
193 "enter_uploading": func(e *fsm.Event) { onuDeviceEntry.enterUploadingState(e) },
194 "enter_examining_mds": func(e *fsm.Event) { onuDeviceEntry.enterExaminingMdsState(e) },
195 "enter_resynchronizing": func(e *fsm.Event) { onuDeviceEntry.enterResynchronizingState(e) },
196 "enter_auditing": func(e *fsm.Event) { onuDeviceEntry.enterAuditingState(e) },
197 "enter_out_of_sync": func(e *fsm.Event) { onuDeviceEntry.enterOutOfSyncState(e) },
198 "enter_in_sync": func(e *fsm.Event) { onuDeviceEntry.enterInSyncState(e) },
199 },
200 )
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000201 // Omci related Mib download state machine
202 mibDownloadChan := make(chan Message, 2048)
203 onuDeviceEntry.pMibDownloadFsm = NewAdapterFsm("MibDownload", device_id, mibDownloadChan)
204 onuDeviceEntry.pMibDownloadFsm.pFsm = fsm.NewFSM(
205 "disabled",
206 fsm.Events{
207
208 {Name: "start", Src: []string{"disabled"}, Dst: "starting"},
209
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000210 {Name: "create_gal", Src: []string{"starting"}, Dst: "creatingGal"},
211 {Name: "rx_gal_resp", Src: []string{"creatingGal"}, Dst: "settingOnu2g"},
212 {Name: "rx_onu2g_resp", Src: []string{"settingOnu2g"}, Dst: "bridgeInit"},
213 // the bridge state is used for multi ME config for alle UNI related ports
214 // maybe such could be reflected in the state machine as well (port number parametrized)
215 // but that looks not straightforward here - so we keep it simple here for the beginning(?)
216 {Name: "rx_bridge_resp", Src: []string{"bridgeInit"}, Dst: "downloaded"},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000217
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000218 {Name: "timeout_simple", Src: []string{"creatingGal", "settingOnu2g"}, Dst: "starting"},
219 {Name: "timeout_bridge", Src: []string{"bridgeInit"}, Dst: "starting"},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000220
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000221 {Name: "reset", Src: []string{"starting", "creatingGal", "settingOnu2g",
222 "bridgeInit", "downloaded"}, Dst: "resetting"},
223 // exceptional treatment for all states except "resetting"
224 {Name: "restart", Src: []string{"starting", "creatingGal", "settingOnu2g",
225 "bridgeInit", "downloaded", "resetting"}, Dst: "disabled"},
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000226 },
227
228 fsm.Callbacks{
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +0000229 "enter_state": func(e *fsm.Event) { onuDeviceEntry.pMibDownloadFsm.logFsmStateChange(e) },
230 "enter_starting": func(e *fsm.Event) { onuDeviceEntry.enterDLStartingState(e) },
231 "enter_creatingGal": func(e *fsm.Event) { onuDeviceEntry.enterCreatingGalState(e) },
232 "enter_settingOnu2g": func(e *fsm.Event) { onuDeviceEntry.enterSettingOnu2gState(e) },
233 "enter_bridgeInit": func(e *fsm.Event) { onuDeviceEntry.enterBridgeInitState(e) },
234 "enter_downloaded": func(e *fsm.Event) { onuDeviceEntry.enterDownloadedState(e) },
235 "enter_resetting": func(e *fsm.Event) { onuDeviceEntry.enterResettingState(e) },
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000236 },
237 )
238 if onuDeviceEntry.pMibDownloadFsm == nil || onuDeviceEntry.pMibDownloadFsm.pFsm == nil {
239 logger.Error("MibDownloadFsm could not be instantiated!!")
240 // some specifc error treatment - or waiting for crash ???
241 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000242
243 // Alarm Synchronization Database
244 //self._alarm_db = None
245 //self._alarm_database_cls = support_classes['alarm-synchronizer']['database']
246 return &onuDeviceEntry
247}
248
249//Start starts (logs) the omci agent
250func (oo *OnuDeviceEntry) Start(ctx context.Context) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 logger.Info("starting-OnuDeviceEntry")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000252
253 oo.PDevOmciCC = NewOmciCC(ctx, oo, oo.deviceID, oo.baseDeviceHandler,
254 oo.coreProxy, oo.adapterProxy)
255
256 //TODO .....
257 //mib_db.start()
258 oo.started = true
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 logger.Info("OnuDeviceEntry-started, but not yet mib_db!!!")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000260 return nil
261}
262
263//Stop terminates the session
264func (oo *OnuDeviceEntry) Stop(ctx context.Context) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000265 logger.Info("stopping-OnuDeviceEntry")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000266 oo.started = false
267 //oo.exitChannel <- 1
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 logger.Info("OnuDeviceEntry-stopped")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000269 return nil
270}
271
272//Relay the InSync message via Handler to Rw core - Status update
273func (oo *OnuDeviceEntry) transferSystemEvent(dev_Event OnuDeviceEvent) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000274 logger.Debugw("relaying system-event", log.Fields{"Event": dev_Event})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000275 // decouple the handler transfer from further processing here
276 // TODO!!! check if really no synch is required within the system e.g. to ensure following steps ..
277 if dev_Event == MibDatabaseSync {
278 if oo.devState < MibDatabaseSync { //devState has not been synced yet
279 oo.devState = MibDatabaseSync
280 go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
281 //TODO!!! device control: next step: start MIB capability verification from here ?!!!
282 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283 logger.Debugw("mibinsync-event in some already synced state - ignored", log.Fields{"state": oo.devState})
284 }
285 } else if dev_Event == MibDownloadDone {
286 if oo.devState < MibDownloadDone { //devState has not been synced yet
287 oo.devState = MibDownloadDone
288 go oo.baseDeviceHandler.DeviceStateUpdate(dev_Event)
289 } else {
290 logger.Debugw("mibdownloaddone-event was already seen - ignored", log.Fields{"state": oo.devState})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000291 }
292 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 logger.Warnw("device-event not yet handled", log.Fields{"state": dev_Event})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000294 }
295 return nil
296}