blob: 40632c2be9252d72a1e17ad2c1f6e562651388ad [file] [log] [blame]
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2021-2023 Open Networking Foundation (ONF) and the ONF Contributors
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303 *
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
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package almgr provides the utilities for managing alarm notifications
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package almgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053019
20import (
21 "context"
22 "errors"
23 "fmt"
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +000024 "reflect"
25 "sync"
26 "time"
27
Himani Chawlad3dac422021-03-13 02:31:31 +053028 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000029 "github.com/opencord/omci-lib-go/v2"
30 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040031 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
32 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000033 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
praneeth nalmas5a0a5502022-12-23 15:57:00 +053034 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo7d3c5582021-08-11 18:09:44 -040035 "github.com/opencord/voltha-protos/v5/go/voltha"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053036)
37
38const (
39 circuitPackClassID = me.CircuitPackClassID
40 physicalPathTerminationPointEthernetUniClassID = me.PhysicalPathTerminationPointEthernetUniClassID
41 onuGClassID = me.OnuGClassID
42 aniGClassID = me.AniGClassID
Himani Chawlad3dac422021-03-13 02:31:31 +053043 defaultTimeoutDelay = 10
44 alarmBitMapSizeBytes = 28
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053045)
46
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000047// events of alarm sync FSM
Himani Chawlad3dac422021-03-13 02:31:31 +053048const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000049 AsEvStart = "AsEvStart"
50 AsEvStop = "AsEvStop"
51 AsEvAudit = "AsEvAudit"
52 AsEvSync = "AsEvSync"
53 AsEvSuccess = "AsEvSuccess"
54 AsEvFailure = "AsEvFailure"
55 AsEvResync = "AsEvResync"
Himani Chawlad3dac422021-03-13 02:31:31 +053056)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000057
58// states of alarm sync FSM
Himani Chawlad3dac422021-03-13 02:31:31 +053059const (
Himani Chawlad3dac422021-03-13 02:31:31 +053060 asStStarting = "asStStarting"
61 asStDisabled = "asStDisabled"
62 asStInSync = "asStInSync"
63 asStAuditing = "asStAuditing"
64 asStResynchronizing = "asStResynchronizing"
65 asStIdle = "asStIdle"
66)
67
68//const cAsFsmIdleState = asStIdle not using idle state currently
69
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053070type alarmInfo struct {
71 classID me.ClassID
72 instanceID uint16
73 alarmNo uint8
74}
75
76type alarms map[alarmInfo]struct{}
77
Himani Chawlad3dac422021-03-13 02:31:31 +053078type meAlarmKey struct {
79 classID me.ClassID
80 instanceID uint16
81}
82
83type alarmBitMapDB map[meAlarmKey][alarmBitMapSizeBytes]byte
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053084
85type onuDevice struct {
86 classID me.ClassID
87 alarmno uint8
88}
89type onuDeviceEvent struct {
90 EventName string
91 EventCategory eventif.EventCategory
92 EventSubCategory eventif.EventSubCategory
93 EventDescription string
94}
95
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000096// OnuAlarmManager holds alarm manager related data
97type OnuAlarmManager struct {
98 deviceID string
99 pDeviceHandler cmn.IdeviceHandler
100 pOnuDeviceEntry cmn.IonuDeviceEntry
101 eventProxy eventif.EventProxy
102 StopProcessingOmciMessages chan bool
103 eventChannel chan cmn.Message
104 onuAlarmManagerLock sync.RWMutex
105 processMessage bool
106 activeAlarms alarms
107 alarmBitMapDB alarmBitMapDB
108 onuEventsList map[onuDevice]onuDeviceEvent
109 lastAlarmSequence uint8
110 AlarmSyncFsm *cmn.AdapterFsm
111 oltDbCopy alarmBitMapDB
112 onuDBCopy alarmBitMapDB
113 bufferedNotifications []*omci.AlarmNotificationMsg
114 alarmUploadSeqNo uint16
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000115 alarmUploadNoOfCmdsOrMEs uint16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000116 StopAlarmAuditTimer chan struct{}
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000117 isExtendedOmci bool
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530118 AsyncAlarmsCommChan chan struct{}
119 isAsyncAlarmRequest bool
120 onuAlarmRequestLock sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121}
122
123// NewAlarmManager - TODO: add comment
124func NewAlarmManager(ctx context.Context, dh cmn.IdeviceHandler, onuDev cmn.IonuDeviceEntry) *OnuAlarmManager {
125 var alarmManager OnuAlarmManager
126 alarmManager.deviceID = dh.GetDeviceID()
127 logger.Debugw(ctx, "init-alarm-manager", log.Fields{"device-id": alarmManager.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530128 alarmManager.pDeviceHandler = dh
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000129 alarmManager.pOnuDeviceEntry = onuDev
130 alarmManager.eventProxy = dh.GetEventProxy() // Or event proxy should be on cluster address ??
131 alarmManager.eventChannel = make(chan cmn.Message)
132 alarmManager.StopProcessingOmciMessages = make(chan bool)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530133 alarmManager.processMessage = false
134 alarmManager.activeAlarms = make(map[alarmInfo]struct{})
Himani Chawlad3dac422021-03-13 02:31:31 +0530135 alarmManager.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000136 alarmManager.StopAlarmAuditTimer = make(chan struct{})
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530137 alarmManager.AsyncAlarmsCommChan = make(chan struct{})
138 alarmManager.isAsyncAlarmRequest = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530139 alarmManager.onuEventsList = map[onuDevice]onuDeviceEvent{
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530140 {classID: circuitPackClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
141 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
142 {classID: circuitPackClassID, alarmno: 2}: {EventName: "ONU_SELF_TEST_FAIL",
143 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
144 {classID: circuitPackClassID, alarmno: 3}: {EventName: "ONU_LASER_EOL",
145 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser EOL"},
146 {classID: circuitPackClassID, alarmno: 4}: {EventName: "ONU_TEMP_YELLOW",
147 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
148 {classID: circuitPackClassID, alarmno: 5}: {EventName: "ONU_TEMP_RED",
149 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
150 {classID: physicalPathTerminationPointEthernetUniClassID, alarmno: 0}: {EventName: "ONU_Ethernet_UNI", EventCategory: voltha.EventCategory_EQUIPMENT,
151 EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "LAN Loss Of Signal"},
152 {classID: onuGClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
153 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
154 {classID: onuGClassID, alarmno: 6}: {EventName: "ONU_SELF_TEST_FAIL",
155 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
156 {classID: onuGClassID, alarmno: 7}: {EventName: "ONU_DYING_GASP",
157 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu DYING_GASP"},
158 {classID: onuGClassID, alarmno: 8}: {EventName: "ONU_TEMP_YELLOW",
159 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
160 {classID: onuGClassID, alarmno: 9}: {EventName: "ONU_TEMP_RED",
161 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
162 {classID: onuGClassID, alarmno: 10}: {EventName: "ONU_VOLTAGE_YELLOW",
163 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage yellow"},
164 {classID: onuGClassID, alarmno: 11}: {EventName: "ONU_VOLTAGE_RED",
165 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage red"},
166 {classID: aniGClassID, alarmno: 0}: {EventName: "ONU_LOW_RX_OPTICAL",
167 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low rx optical power"},
168 {classID: aniGClassID, alarmno: 1}: {EventName: "ONU_HIGH_RX_OPTICAL",
169 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high rx optical power"},
170 {classID: aniGClassID, alarmno: 4}: {EventName: "ONU_LOW_TX_OPTICAL",
171 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low tx optical power"},
172 {classID: aniGClassID, alarmno: 5}: {EventName: "ONU_HIGH_TX_OPTICAL",
173 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high tx optical power"},
174 {classID: aniGClassID, alarmno: 6}: {EventName: "ONU_LASER_BIAS_CURRENT",
175 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser bias current"},
176 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000177 alarmManager.AlarmSyncFsm = cmn.NewAdapterFsm("AlarmSync", alarmManager.deviceID, alarmManager.eventChannel)
178 alarmManager.AlarmSyncFsm.PFsm = fsm.NewFSM(
Himani Chawlad3dac422021-03-13 02:31:31 +0530179 asStDisabled,
180 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000181 {Name: AsEvStart, Src: []string{asStDisabled}, Dst: asStStarting},
182 {Name: AsEvAudit, Src: []string{asStStarting, asStInSync}, Dst: asStAuditing},
183 {Name: AsEvSync, Src: []string{asStStarting}, Dst: asStInSync},
184 {Name: AsEvSuccess, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStInSync},
185 {Name: AsEvFailure, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStAuditing},
186 {Name: AsEvResync, Src: []string{asStAuditing}, Dst: asStResynchronizing},
187 {Name: AsEvStop, Src: []string{asStDisabled, asStStarting, asStAuditing, asStInSync, asStIdle, asStResynchronizing}, Dst: asStDisabled},
Himani Chawlad3dac422021-03-13 02:31:31 +0530188 },
189 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000190 "enter_state": func(e *fsm.Event) { alarmManager.AlarmSyncFsm.LogFsmStateChange(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530191 "enter_" + asStStarting: func(e *fsm.Event) { alarmManager.asFsmStarting(ctx, e) },
192 "enter_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmAuditing(ctx, e) },
193 "enter_" + asStInSync: func(e *fsm.Event) { alarmManager.asFsmInSync(ctx, e) },
194 "enter_" + asStResynchronizing: func(e *fsm.Event) { alarmManager.asFsmResynchronizing(ctx, e) },
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530195 "leave_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmLeaveAuditing(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530196 },
197 )
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530198 return &alarmManager
199}
200
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000201func (am *OnuAlarmManager) asFsmStarting(ctx context.Context, e *fsm.Event) {
202 logger.Debugw(ctx, "alarm-sync-fsm-start-processing-msgs-in-state", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530203 go am.processAlarmSyncMessages(ctx)
204 // Start the first audit, if audit interval configured, else reach the sync state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000205 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530206 select {
207 //Transition into auditing state, using a very shorter timeout delay here, hence it is the first audit
208 case <-time.After(defaultTimeoutDelay * time.Second):
209 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000210 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
211 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530212 }
213 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000214 case <-am.StopAlarmAuditTimer:
215 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530216 return
217 }
218 } else {
219 // Transition into sync state directly.
220 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000221 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSync); err != nil {
222 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-sync", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530223 }
224 }()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530225 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530226}
227
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000228func (am *OnuAlarmManager) asFsmAuditing(ctx context.Context, e *fsm.Event) {
229 logger.Debugw(ctx, "alarm-sync-fsm-start-auditing", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530230 // Always reset the buffered notifications and db copies before starting the audit
231 am.onuAlarmManagerLock.Lock()
232 am.bufferedNotifications = make([]*omci.AlarmNotificationMsg, 0)
233 am.oltDbCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
234 am.onuDBCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
235 am.onuAlarmManagerLock.Unlock()
236 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000237 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
238 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-failure", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530239 }
240 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000241 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarm(log.WithSpanFromContext(context.TODO(), ctx), 0,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000242 am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530243 // Transition to failure so that alarm sync can be restarted again
244 go failureTransition()
245 }
246}
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530247func (am *OnuAlarmManager) asFsmLeaveAuditing(ctx context.Context, e *fsm.Event) {
248 logger.Debugw(ctx, "alarm-sync-fsm-leave-auditing state", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
249 if am.isAsyncAlarmRequest {
250 logger.Errorw(ctx, "alarm-sync-fsm-leave-auditing state process the updated ONU alarms ", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
251 am.AsyncAlarmsCommChan <- struct{}{}
252 am.isAsyncAlarmRequest = false
Himani Chawlad3dac422021-03-13 02:31:31 +0530253
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530254 }
255}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000256func (am *OnuAlarmManager) asFsmResynchronizing(ctx context.Context, e *fsm.Event) {
257 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530258 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
260 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-failure", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530261 }
262 }
263 // See if there is any onu only diff, meaning the class and entity is only in onu DB
264 for alarm := range am.onuDBCopy {
265 if _, exists := am.oltDbCopy[meAlarmKey{
266 classID: alarm.classID,
267 instanceID: alarm.instanceID,
268 }]; !exists {
269 // We need to raise all such alarms as OLT wont have received notification for these alarms
270 omciAlarmMessage := &omci.AlarmNotificationMsg{
271 MeBasePacket: omci.MeBasePacket{
272 EntityClass: alarm.classID,
273 EntityInstance: alarm.instanceID,
274 },
275 AlarmBitmap: am.onuDBCopy[alarm],
276 }
277 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000278 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530279 // Transition to failure.
280 go failureTransition()
281 return
282 }
283 }
284 }
285 // See if there is any olt only diff, meaning the class and entity is only in olt DB
286 for alarm := range am.oltDbCopy {
287 if _, exists := am.onuDBCopy[meAlarmKey{
288 classID: alarm.classID,
289 instanceID: alarm.instanceID,
290 }]; !exists {
291 // We need to clear all such alarms as OLT might have stale data and the alarms are already cleared.
292 omciAlarmMessage := &omci.AlarmNotificationMsg{
293 MeBasePacket: omci.MeBasePacket{
294 EntityClass: alarm.classID,
295 EntityInstance: alarm.instanceID,
296 },
297 AlarmBitmap: am.oltDbCopy[alarm],
298 }
299 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000300 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530301 // Transition to failure
302 go failureTransition()
303 return
304 }
305 }
306 }
307 // See if there is any attribute difference
308 for alarm := range am.onuDBCopy {
309 if _, exists := am.oltDbCopy[alarm]; exists {
310 if am.onuDBCopy[alarm] != am.oltDbCopy[alarm] {
311 omciAlarmMessage := &omci.AlarmNotificationMsg{
312 MeBasePacket: omci.MeBasePacket{
313 EntityClass: alarm.classID,
314 EntityInstance: alarm.instanceID,
315 },
316 AlarmBitmap: am.onuDBCopy[alarm],
317 }
318 // We will assume that onudb is correct always in this case and process the changed bitmap.
319 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000320 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530321 // Transition to failure
322 go failureTransition()
323 return
324 }
325 }
326 }
327 }
328 // Send the buffered notifications if no failure.
329 for _, notif := range am.bufferedNotifications {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000330 logger.Debugw(ctx, "processing-buffered-alarm-notification", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530331 "notification": notif})
332 if err := am.processAlarmData(ctx, notif); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000333 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530334 go failureTransition()
335 }
336 }
337 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
339 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-sync", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530340 }
341 }()
342}
343
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000344func (am *OnuAlarmManager) asFsmInSync(ctx context.Context, e *fsm.Event) {
345 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
346 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530347 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348 case <-time.After(am.pDeviceHandler.GetAlarmAuditInterval()):
Himani Chawlad3dac422021-03-13 02:31:31 +0530349 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
351 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530352 }
353 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000354 case <-am.StopAlarmAuditTimer:
355 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530356 return
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530357
358 case <-am.AsyncAlarmsCommChan:
359 go func() {
360 logger.Debugw(ctx, "On demand Auditing the ONU for Alarms ", log.Fields{"device-id": am.deviceID})
361 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
362 logger.Errorw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing, use current snapshot of alarms", log.Fields{"device-id": am.deviceID, "err": err})
363 am.isAsyncAlarmRequest = false
364 am.AsyncAlarmsCommChan <- struct{}{}
365 }
366 }()
367
Himani Chawlad3dac422021-03-13 02:31:31 +0530368 }
369 }
370}
371
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000372func (am *OnuAlarmManager) processAlarmSyncMessages(ctx context.Context) {
373 logger.Debugw(ctx, "start-routine-to-process-omci-messages-for-alarm-sync", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530374 for {
Himani Chawla1472c682021-03-17 17:11:14 +0530375 select {
376 case message, ok := <-am.eventChannel:
377 if !ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 logger.Info(ctx, "alarm-sync-omci-message-could-not-be-read-from-channel", log.Fields{"device-id": am.deviceID})
Himani Chawla1472c682021-03-17 17:11:14 +0530379 continue
380 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000381 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530382
Himani Chawla1472c682021-03-17 17:11:14 +0530383 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 case cmn.OMCI:
385 msg, _ := message.Data.(cmn.OmciMessage)
Himani Chawla1472c682021-03-17 17:11:14 +0530386 am.handleOmciMessage(ctx, msg)
387 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 logger.Warn(ctx, "alarm-sync-unknown-message-type-received", log.Fields{"device-id": am.deviceID, "message.Type": message.Type})
Himani Chawla1472c682021-03-17 17:11:14 +0530389 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000390 case <-am.StopProcessingOmciMessages:
391 logger.Infow(ctx, "alarm-manager-stop-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawla1472c682021-03-17 17:11:14 +0530392 am.onuAlarmManagerLock.Lock()
393 am.processMessage = false
394 am.activeAlarms = nil
395 am.alarmBitMapDB = nil
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000396 am.alarmUploadNoOfCmdsOrMEs = 0
Himani Chawla1472c682021-03-17 17:11:14 +0530397 am.alarmUploadSeqNo = 0
398 am.onuAlarmManagerLock.Unlock()
399 return
400
Himani Chawlad3dac422021-03-13 02:31:31 +0530401 }
402 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530403}
404
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405func (am *OnuAlarmManager) handleOmciMessage(ctx context.Context, msg cmn.OmciMessage) {
406 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530407 "msg-type": msg.OmciMsg.MessageType, "msg": msg})
408 switch msg.OmciMsg.MessageType {
409 case omci.GetAllAlarmsResponseType:
410 am.handleOmciGetAllAlarmsResponseMessage(ctx, msg)
411 case omci.GetAllAlarmsNextResponseType:
412 am.handleOmciGetAllAlarmNextResponseMessage(ctx, msg)
413 default:
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000414 logger.Warnw(ctx, "unknown-message-type", log.Fields{"device-id": am.deviceID, "msg-type": msg.OmciMsg.MessageType})
Himani Chawlad3dac422021-03-13 02:31:31 +0530415
416 }
417}
418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000419func (am *OnuAlarmManager) handleOmciGetAllAlarmsResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530420 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsResponse)
421 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000422 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530423 return
424 }
425 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsResponse)
426 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000427 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530428 return
429 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000430 logger.Debugw(ctx, "get-all-alarm-response-data", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
431 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
432 logger.Debugw(ctx, "alarm-sync-fsm-is-disabled-ignoring-response-message", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawlad3dac422021-03-13 02:31:31 +0530433 return
434 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000435 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000436 am.alarmUploadNoOfCmdsOrMEs = msgObj.NumberOfCommands
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000437 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530438 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
440 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-failure", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530441 }
442 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000443 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000444 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Himani Chawlad3dac422021-03-13 02:31:31 +0530445 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530446 am.resetAlarmSequence()
447 // Get a copy of the alarm bit map db.
448 for alarms, bitmap := range am.alarmBitMapDB {
449 am.oltDbCopy[alarms] = bitmap
450 }
451 am.onuAlarmManagerLock.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000452 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000453 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530454 // Transition to failure
455 go failureTransition()
456 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000457 } else if am.alarmUploadNoOfCmdsOrMEs == 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530458 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530459 am.resetAlarmSequence()
460 // Get a copy of the alarm bit map db.
461 for alarms, bitmap := range am.alarmBitMapDB {
462 am.oltDbCopy[alarms] = bitmap
463 }
464 am.onuAlarmManagerLock.Unlock()
465 if am.isAlarmDBDiffPresent(ctx) {
466 // transition to resync state
467 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
469 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-resynchronizing", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530470 }
471 }()
472 } else {
473 // Transition to sync state
474 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000475 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
476 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-sync", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530477 }
478 }()
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530479
Himani Chawlad3dac422021-03-13 02:31:31 +0530480 }
481 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 logger.Errorw(ctx, "invalid-number-of-commands-received", log.Fields{"device-id": am.deviceID,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000483 "upload-no-of-cmds": am.alarmUploadNoOfCmdsOrMEs, "upload-seq-no": am.alarmUploadSeqNo})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000484 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530485 go failureTransition()
486 }
487}
488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000489func (am *OnuAlarmManager) handleOmciGetAllAlarmNextResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530490 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsNextResponse)
491
492 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530494 return
495 }
496 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsNextResponse)
497 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530499 return
500 }
501 logger.Debugw(ctx, "get-all-alarms-next-response-data",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawlad3dac422021-03-13 02:31:31 +0530503 meClassID := msgObj.AlarmEntityClass
504 meEntityID := msgObj.AlarmEntityInstance
505 meAlarmBitMap := msgObj.AlarmBitMap
506
507 am.onuAlarmManagerLock.Lock()
508 am.onuDBCopy[meAlarmKey{
509 classID: meClassID,
510 instanceID: meEntityID,
511 }] = meAlarmBitMap
512 am.onuAlarmManagerLock.Unlock()
513 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000514 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
515 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-failure", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530516 }
517 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000518 if msg.OmciMsg.DeviceIdentifier == omci.ExtendedIdent {
519 logger.Debugw(ctx, "get-all-alarms-next-response-additional-data",
520 log.Fields{"device-id": am.deviceID, "additional-data": msgObj.AdditionalAlarms})
521
522 for _, additionalAlarmReport := range msgObj.AdditionalAlarms {
523 meClassID := additionalAlarmReport.AlarmEntityClass
524 meEntityID := additionalAlarmReport.AlarmEntityInstance
525 meAlarmBitMap := additionalAlarmReport.AlarmBitMap
526
527 am.onuAlarmManagerLock.Lock()
528 am.onuDBCopy[meAlarmKey{
529 classID: meClassID,
530 instanceID: meEntityID,
531 }] = meAlarmBitMap
532 am.onuAlarmManagerLock.Unlock()
533
534 am.IncrementAlarmUploadSeqNo()
535 }
536 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000537 am.onuAlarmManagerLock.RLock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000538 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000539 am.onuAlarmManagerLock.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000541 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530542 // Transition to failure
543 go failureTransition()
544 } //TODO: needs to handle timeouts
545 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000546 am.onuAlarmManagerLock.RUnlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530547 if am.isAlarmDBDiffPresent(ctx) {
548 // transition to resync state
549 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
551 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-resynchronizing", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530552 }
553 }()
554 } else {
555 // Transition to sync state
556 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
558 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-sync", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530559 }
560 }()
561 }
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530562
Himani Chawlad3dac422021-03-13 02:31:31 +0530563 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530564}
565
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000566// StartOMCIAlarmMessageProcessing - TODO: add comment: add comment
567func (am *OnuAlarmManager) StartOMCIAlarmMessageProcessing(ctx context.Context) {
568 logger.Infow(ctx, "alarm-manager-start-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530569 am.onuAlarmManagerLock.Lock()
570 am.processMessage = true
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530571 if am.activeAlarms == nil {
572 am.activeAlarms = make(map[alarmInfo]struct{})
573 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530574 am.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000575 // when instantiating alarm manager it was too early, but now we can check for ONU's extended OMCI support
576 am.isExtendedOmci = am.pOnuDeviceEntry.GetPersIsExtOmciSupported()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530577 am.onuAlarmManagerLock.Unlock()
Himani Chawla1472c682021-03-17 17:11:14 +0530578 am.flushAlarmSyncChannels(ctx) // Need to do this first as there might be stale data on the channels and the start state waits on same channels
579
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
581 if err := am.AlarmSyncFsm.PFsm.Event(AsEvStart); err != nil {
582 logger.Errorw(ctx, "alarm-sync-fsm-can-not-go-to-state-starting", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530583 return
584 }
585 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 logger.Errorw(ctx, "wrong-state-of-alarm-sync-fsm-want-disabled", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current()),
587 "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530588 return
589 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 logger.Debugw(ctx, "alarm-sync-fsm-started", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current())})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530591}
592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593// HandleOmciAlarmNotificationMessage - TODO: add comment
594func (am *OnuAlarmManager) HandleOmciAlarmNotificationMessage(ctx context.Context, msg cmn.OmciMessage) {
595 logger.Debugw(ctx, "omci-alarm-notification-msg", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530596 "msg-type": msg.OmciMsg.MessageType})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530597
Himani Chawla7998aa92021-04-07 14:16:52 +0530598 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeAlarmNotification)
599 if msgLayer == nil {
600 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530602 return
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530603 }
Himani Chawla7998aa92021-04-07 14:16:52 +0530604 msgObj, msgOk := msgLayer.(*omci.AlarmNotificationMsg)
605 if !msgOk {
606 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530608 return
609 }
610 //Alarm Notification decoding at omci lib validates that the me class ID supports the
611 // alarm notifications.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612 logger.Debugw(ctx, "alarm-notification-data-received", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawla7998aa92021-04-07 14:16:52 +0530613 if err := am.processAlarmData(ctx, msgObj); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000614 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530615 }
616
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530617}
618
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000619func (am *OnuAlarmManager) processAlarmData(ctx context.Context, msg *omci.AlarmNotificationMsg) error {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530620 classID := msg.EntityClass
621 sequenceNo := msg.AlarmSequenceNumber
622 meInstance := msg.EntityInstance
623 alarmBitmap := msg.AlarmBitmap
624 logger.Debugw(ctx, "processing-alarm-data", log.Fields{"class-id": classID, "instance-id": meInstance,
625 "alarmBitMap": alarmBitmap, "sequence-no": sequenceNo})
Himani Chawla7998aa92021-04-07 14:16:52 +0530626 am.onuAlarmManagerLock.Lock()
627 defer am.onuAlarmManagerLock.Unlock()
628 if !am.processMessage {
629 logger.Warnw(ctx, "ignoring-alarm-notification-received-for-me-as-channel-for-processing-is-closed",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000630 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530631 return fmt.Errorf("alarm-manager-is-in-stopped-state")
632 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000633 if _, present := am.pOnuDeviceEntry.GetOnuDB().MeDb[classID][meInstance]; !present {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000634 logger.Errorw(ctx, "me-class-instance-not-present",
635 log.Fields{"class-id": classID, "instance-id": meInstance, "device-id": am.deviceID})
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530636 return fmt.Errorf("me-class-%d-instance-%d-not-present", classID, meInstance)
637 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530638 if sequenceNo > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000639 if am.AlarmSyncFsm.PFsm.Is(asStAuditing) || am.AlarmSyncFsm.PFsm.Is(asStResynchronizing) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530640 am.bufferedNotifications = append(am.bufferedNotifications, msg)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 logger.Debugw(ctx, "adding-notification-to-buffered-notification-list", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530642 "notification": msg})
643 return nil
Andrea Campanellace915292021-03-12 17:59:35 +0000644 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530645 am.incrementAlarmSequence()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 if sequenceNo != am.lastAlarmSequence && am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530647 // signal early audit, if no match(if we are reaching here it means that audit is not going on currently)
648 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
650 logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing", log.Fields{"device-id": am.deviceID, "err": err})
Himani Chawlad3dac422021-03-13 02:31:31 +0530651 }
652 }()
653 }
654 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530655 entity, omciErr := me.LoadManagedEntityDefinition(classID,
656 me.ParamData{EntityID: meInstance})
657 if omciErr.StatusCode() != me.Success {
658 //log error and return
659 logger.Error(ctx, "unable-to-get-managed-entity", log.Fields{"class-id": classID, "instance-id": meInstance})
660 return fmt.Errorf("unable-to-get-managed-entity-class-%d-instance-%d", classID, meInstance)
661 }
662 meAlarmMap := entity.GetAlarmMap()
663 if meAlarmMap == nil {
664 logger.Error(ctx, "unable-to-get-managed-entity-alarm-map", log.Fields{"class-id": classID, "instance-id": meInstance})
665 return fmt.Errorf("unable-to-get-managed-entity-alarm-map-%d-instance-%d", classID, meInstance)
666 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530667
668 am.alarmBitMapDB[meAlarmKey{
669 classID: classID,
670 instanceID: meInstance,
671 }] = alarmBitmap
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530672 // Loop over the supported alarm list for this me
673 for alarmNo := range meAlarmMap {
674 // Check if alarmNo was previously active in the alarms, if yes clear it and remove it from active alarms
675 _, exists := am.activeAlarms[alarmInfo{
676 classID: classID,
677 instanceID: meInstance,
678 alarmNo: alarmNo,
679 }]
680 if exists {
681 // Clear this alarm if It is cleared now, in that case IsAlarmClear would return true
682 cleared, err := msg.IsAlarmClear(alarmNo)
683 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000684 logger.Warnw(ctx, "unable-to-find-out-alarm-is-cleared", log.Fields{"device-id": am.deviceID,
685 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530686 return err
687 }
688 if cleared {
689 // Clear this alarm.
690 am.clearAlarm(ctx, classID, meInstance, alarmNo)
691 }
692 } else {
693 // If alarm entry was not present in the list of active alarms, we need to see if this alarm is now active
694 // or not, if yes then raise it.
695 raised, err := msg.IsAlarmActive(alarmNo)
696 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000697 logger.Warnw(ctx, "unable-to-find-out-alarm-is-raised", log.Fields{"device-id": am.deviceID,
698 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530699 return err
700 }
701 if raised {
702 am.raiseAlarm(ctx, classID, meInstance, alarmNo)
703 }
704 }
705 }
706 return nil
707}
708
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000709func (am *OnuAlarmManager) raiseAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530710 am.activeAlarms[alarmInfo{
711 classID: classID,
712 instanceID: instanceID,
713 alarmNo: alarm,
714 }] = struct{}{}
Himani Chawlad3dac422021-03-13 02:31:31 +0530715
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530716 go am.sendAlarm(ctx, classID, instanceID, alarm, true)
717}
718
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000719func (am *OnuAlarmManager) clearAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530720 go am.sendAlarm(ctx, classID, instanceID, alarm, false)
721 delete(am.activeAlarms, alarmInfo{
722 classID: classID,
723 instanceID: instanceID,
724 alarmNo: alarm,
725 })
Himani Chawlad3dac422021-03-13 02:31:31 +0530726 key := meAlarmKey{
727 classID: classID,
728 instanceID: instanceID,
729 }
730 if am.alarmBitMapDB[key] == [alarmBitMapSizeBytes]byte{0} {
731 delete(am.alarmBitMapDB, key)
732 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530733}
734
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000735func (am *OnuAlarmManager) getIntfIDAlarm(ctx context.Context, classID me.ClassID, instanceID uint16) *uint32 {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530736 var intfID *uint32
737 if classID == circuitPackClassID || classID == physicalPathTerminationPointEthernetUniClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000738 for _, uniPort := range *am.pDeviceHandler.GetUniEntityMap() {
739 if uniPort.EntityID == instanceID {
740 intfID = &uniPort.PortNo
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530741 return intfID
742 }
743 }
744 } else if classID == aniGClassID || classID == onuGClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000745 intfID = am.pDeviceHandler.GetPonPortNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530746 return intfID
747 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000748 logger.Warnw(ctx, "me-not-supported", log.Fields{"device-id": am.deviceID, "class-id": classID, "instance-id": instanceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530749 }
750 return nil
751}
752
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000753func (am *OnuAlarmManager) sendAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8, raised bool) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530754 context := make(map[string]string)
755 intfID := am.getIntfIDAlarm(ctx, classID, instanceID)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000756 onuID := am.deviceID
757 serialNo := am.pOnuDeviceEntry.GetPersSerialNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530758 if intfID == nil {
759 logger.Warn(ctx, "intf-id-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
760 return
761 }
762 context["onu-intf-id"] = fmt.Sprintf("%d", *intfID)
763 context["onu-id"] = onuID
764 context["onu-serial-number"] = serialNo
765
ozgecanetsia2f05ed32021-05-31 17:13:48 +0300766 raisedTimestamp := time.Now().Unix()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530767 eventDetails, err := am.getDeviceEventData(ctx, classID, alarm)
768 if err != nil {
769 logger.Warn(ctx, "event-details-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
770 return
771 }
772 suffixDesc := "Raised"
773 if !raised {
774 suffixDesc = "Cleared"
775 }
776 deviceEvent := &voltha.DeviceEvent{
777 ResourceId: onuID,
778 DeviceEventName: fmt.Sprintf("%s_RAISE_EVENT", eventDetails.EventName),
779 Description: fmt.Sprintf("%s Event - %s - %s", eventDetails.EventDescription, eventDetails.EventName,
780 suffixDesc),
781 Context: context,
782 }
783 _ = am.eventProxy.SendDeviceEvent(ctx, deviceEvent, eventDetails.EventCategory, eventDetails.EventSubCategory,
784 raisedTimestamp)
785}
Himani Chawlad3dac422021-03-13 02:31:31 +0530786
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000787func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530788 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
789}
790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530792 //alarm sequence number wraps from 255 to 1.
793 if am.lastAlarmSequence == 255 {
794 am.lastAlarmSequence = 1
795 } else {
796 am.lastAlarmSequence++
797 }
798}
799
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530801 am.lastAlarmSequence = 0
802}
803
804// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000805func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530806 // flush alarm sync channel
807 select {
808 case <-am.eventChannel:
809 logger.Debug(ctx, "flushed-alarm-sync-channel")
810 default:
811 }
812 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530814 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
815 default:
816 }
817}
818
819// getDeviceEventData returns the event data for a device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530821 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
822 return onuEventDetails, nil
823 }
824 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
825}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000826
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530827// ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000829 am.onuAlarmManagerLock.Lock()
830 am.alarmUploadSeqNo = 0
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000831 am.alarmUploadNoOfCmdsOrMEs = 0
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000832 am.onuAlarmManagerLock.Unlock()
833}
834
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530835// IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000837 am.onuAlarmManagerLock.Lock()
838 am.alarmUploadSeqNo++
839 am.onuAlarmManagerLock.Unlock()
840}
841
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530842// GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000843func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000844 am.onuAlarmManagerLock.RLock()
845 value := am.alarmUploadSeqNo
846 am.onuAlarmManagerLock.RUnlock()
847 return value
848}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000849
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530850// GetAlarmMgrEventChannel gets alarm manager event channel
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
852 return am.eventChannel
853}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000854
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530855// GetOnuActiveAlarms - Fetch the Active Alarms on demand
856func (am *OnuAlarmManager) GetOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
857
858 am.onuAlarmRequestLock.Lock()
859 defer am.onuAlarmRequestLock.Unlock()
860
861 resp := extension.SingleGetValueResponse{
862 Response: &extension.GetValueResponse{
863 Status: extension.GetValueResponse_OK,
864 Response: &extension.GetValueResponse_OnuActiveAlarms{
865 OnuActiveAlarms: &extension.GetOnuOmciActiveAlarmsResponse{},
866 },
867 },
868 }
869
870 logger.Debugw(ctx, "Requesting to start audit on demand ", log.Fields{"device-id": am.deviceID})
871 am.isAsyncAlarmRequest = true
872
873 am.AsyncAlarmsCommChan <- struct{}{}
874
875 select {
876 case <-time.After(10 * time.Second): //the time to wait needs further discussion.
877 logger.Errorw(ctx, "Couldn't get the Alarms with in 10 seconds stipulated time frame ", log.Fields{"device-id": am.deviceID})
878 am.isAsyncAlarmRequest = false
879
880 case <-am.AsyncAlarmsCommChan:
881 logger.Debugw(ctx, "Received response for the alarm audit ", log.Fields{"device-id": am.deviceID})
882
883 }
884
885 for activeAlarm := range am.activeAlarms {
886
887 onuEventDetails := am.onuEventsList[onuDevice{classID: activeAlarm.classID, alarmno: activeAlarm.alarmNo}]
888 activeAlarmData := extension.AlarmData{}
889 activeAlarmData.ClassId = uint32(activeAlarm.classID)
890 activeAlarmData.InstanceId = uint32(activeAlarm.instanceID)
891 activeAlarmData.Name = onuEventDetails.EventName
892 activeAlarmData.Description = onuEventDetails.EventDescription
893
894 resp.Response.GetOnuActiveAlarms().ActiveAlarms = append(resp.Response.GetOnuActiveAlarms().ActiveAlarms, &activeAlarmData)
895
896 }
897
898 return &resp
899}
900
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000901// PrepareForGarbageCollection - remove references to prepare for garbage collection
902func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
903 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
904 am.pDeviceHandler = nil
905 am.pOnuDeviceEntry = nil
906}