blob: cc6c89823a42576e599c1599cb114015d9210d4b [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"},
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300170 {classID: aniGClassID, alarmno: 2}: {EventName: "ONU_BIT_ERROR_BASED_SIGNAL_FAIL",
171 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu bit error based signal fail"},
172 {classID: aniGClassID, alarmno: 3}: {EventName: "ONU_BIT_ERROR_BASED_SIGNAL_DEGRADE",
173 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu bit error based signal degrade"},
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530174 {classID: aniGClassID, alarmno: 4}: {EventName: "ONU_LOW_TX_OPTICAL",
175 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low tx optical power"},
176 {classID: aniGClassID, alarmno: 5}: {EventName: "ONU_HIGH_TX_OPTICAL",
177 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high tx optical power"},
178 {classID: aniGClassID, alarmno: 6}: {EventName: "ONU_LASER_BIAS_CURRENT",
179 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser bias current"},
180 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000181 alarmManager.AlarmSyncFsm = cmn.NewAdapterFsm("AlarmSync", alarmManager.deviceID, alarmManager.eventChannel)
182 alarmManager.AlarmSyncFsm.PFsm = fsm.NewFSM(
Himani Chawlad3dac422021-03-13 02:31:31 +0530183 asStDisabled,
184 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000185 {Name: AsEvStart, Src: []string{asStDisabled}, Dst: asStStarting},
186 {Name: AsEvAudit, Src: []string{asStStarting, asStInSync}, Dst: asStAuditing},
187 {Name: AsEvSync, Src: []string{asStStarting}, Dst: asStInSync},
188 {Name: AsEvSuccess, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStInSync},
189 {Name: AsEvFailure, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStAuditing},
190 {Name: AsEvResync, Src: []string{asStAuditing}, Dst: asStResynchronizing},
191 {Name: AsEvStop, Src: []string{asStDisabled, asStStarting, asStAuditing, asStInSync, asStIdle, asStResynchronizing}, Dst: asStDisabled},
Himani Chawlad3dac422021-03-13 02:31:31 +0530192 },
193 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000194 "enter_state": func(e *fsm.Event) { alarmManager.AlarmSyncFsm.LogFsmStateChange(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530195 "enter_" + asStStarting: func(e *fsm.Event) { alarmManager.asFsmStarting(ctx, e) },
196 "enter_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmAuditing(ctx, e) },
197 "enter_" + asStInSync: func(e *fsm.Event) { alarmManager.asFsmInSync(ctx, e) },
198 "enter_" + asStResynchronizing: func(e *fsm.Event) { alarmManager.asFsmResynchronizing(ctx, e) },
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530199 "leave_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmLeaveAuditing(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530200 },
201 )
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530202 return &alarmManager
203}
204
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000205func (am *OnuAlarmManager) asFsmStarting(ctx context.Context, e *fsm.Event) {
206 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 +0530207 go am.processAlarmSyncMessages(ctx)
208 // Start the first audit, if audit interval configured, else reach the sync state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000209 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530210 select {
211 //Transition into auditing state, using a very shorter timeout delay here, hence it is the first audit
212 case <-time.After(defaultTimeoutDelay * time.Second):
213 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000214 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
215 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 +0530216 }
217 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000218 case <-am.StopAlarmAuditTimer:
219 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530220 return
221 }
222 } else {
223 // Transition into sync state directly.
224 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000225 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSync); err != nil {
226 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 +0530227 }
228 }()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530229 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530230}
231
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000232func (am *OnuAlarmManager) asFsmAuditing(ctx context.Context, e *fsm.Event) {
233 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 +0530234 // Always reset the buffered notifications and db copies before starting the audit
235 am.onuAlarmManagerLock.Lock()
236 am.bufferedNotifications = make([]*omci.AlarmNotificationMsg, 0)
237 am.oltDbCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
238 am.onuDBCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
239 am.onuAlarmManagerLock.Unlock()
240 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000241 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
242 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 +0530243 }
244 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000245 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarm(log.WithSpanFromContext(context.TODO(), ctx), 0,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000246 am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530247 // Transition to failure so that alarm sync can be restarted again
248 go failureTransition()
249 }
250}
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530251func (am *OnuAlarmManager) asFsmLeaveAuditing(ctx context.Context, e *fsm.Event) {
252 logger.Debugw(ctx, "alarm-sync-fsm-leave-auditing state", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
253 if am.isAsyncAlarmRequest {
254 logger.Errorw(ctx, "alarm-sync-fsm-leave-auditing state process the updated ONU alarms ", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
255 am.AsyncAlarmsCommChan <- struct{}{}
256 am.isAsyncAlarmRequest = false
Himani Chawlad3dac422021-03-13 02:31:31 +0530257
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530258 }
259}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000260func (am *OnuAlarmManager) asFsmResynchronizing(ctx context.Context, e *fsm.Event) {
261 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530262 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000263 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
264 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 +0530265 }
266 }
267 // See if there is any onu only diff, meaning the class and entity is only in onu DB
268 for alarm := range am.onuDBCopy {
269 if _, exists := am.oltDbCopy[meAlarmKey{
270 classID: alarm.classID,
271 instanceID: alarm.instanceID,
272 }]; !exists {
273 // We need to raise all such alarms as OLT wont have received notification for these alarms
274 omciAlarmMessage := &omci.AlarmNotificationMsg{
275 MeBasePacket: omci.MeBasePacket{
276 EntityClass: alarm.classID,
277 EntityInstance: alarm.instanceID,
278 },
279 AlarmBitmap: am.onuDBCopy[alarm],
280 }
281 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000282 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530283 // Transition to failure.
284 go failureTransition()
285 return
286 }
287 }
288 }
289 // See if there is any olt only diff, meaning the class and entity is only in olt DB
290 for alarm := range am.oltDbCopy {
291 if _, exists := am.onuDBCopy[meAlarmKey{
292 classID: alarm.classID,
293 instanceID: alarm.instanceID,
294 }]; !exists {
295 // We need to clear all such alarms as OLT might have stale data and the alarms are already cleared.
296 omciAlarmMessage := &omci.AlarmNotificationMsg{
297 MeBasePacket: omci.MeBasePacket{
298 EntityClass: alarm.classID,
299 EntityInstance: alarm.instanceID,
300 },
301 AlarmBitmap: am.oltDbCopy[alarm],
302 }
303 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000304 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530305 // Transition to failure
306 go failureTransition()
307 return
308 }
309 }
310 }
311 // See if there is any attribute difference
312 for alarm := range am.onuDBCopy {
313 if _, exists := am.oltDbCopy[alarm]; exists {
314 if am.onuDBCopy[alarm] != am.oltDbCopy[alarm] {
315 omciAlarmMessage := &omci.AlarmNotificationMsg{
316 MeBasePacket: omci.MeBasePacket{
317 EntityClass: alarm.classID,
318 EntityInstance: alarm.instanceID,
319 },
320 AlarmBitmap: am.onuDBCopy[alarm],
321 }
322 // We will assume that onudb is correct always in this case and process the changed bitmap.
323 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000324 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530325 // Transition to failure
326 go failureTransition()
327 return
328 }
329 }
330 }
331 }
332 // Send the buffered notifications if no failure.
333 for _, notif := range am.bufferedNotifications {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000334 logger.Debugw(ctx, "processing-buffered-alarm-notification", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530335 "notification": notif})
336 if err := am.processAlarmData(ctx, notif); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530338 go failureTransition()
339 }
340 }
341 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000342 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
343 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 +0530344 }
345 }()
346}
347
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348func (am *OnuAlarmManager) asFsmInSync(ctx context.Context, e *fsm.Event) {
349 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
350 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530351 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 case <-time.After(am.pDeviceHandler.GetAlarmAuditInterval()):
Himani Chawlad3dac422021-03-13 02:31:31 +0530353 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000354 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
355 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 +0530356 }
357 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000358 case <-am.StopAlarmAuditTimer:
359 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530360 return
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530361
362 case <-am.AsyncAlarmsCommChan:
363 go func() {
364 logger.Debugw(ctx, "On demand Auditing the ONU for Alarms ", log.Fields{"device-id": am.deviceID})
365 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
366 logger.Errorw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing, use current snapshot of alarms", log.Fields{"device-id": am.deviceID, "err": err})
367 am.isAsyncAlarmRequest = false
368 am.AsyncAlarmsCommChan <- struct{}{}
369 }
370 }()
371
Himani Chawlad3dac422021-03-13 02:31:31 +0530372 }
373 }
374}
375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376func (am *OnuAlarmManager) processAlarmSyncMessages(ctx context.Context) {
377 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 +0530378 for {
Himani Chawla1472c682021-03-17 17:11:14 +0530379 select {
380 case message, ok := <-am.eventChannel:
381 if !ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 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 +0530383 continue
384 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000385 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530386
Himani Chawla1472c682021-03-17 17:11:14 +0530387 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 case cmn.OMCI:
389 msg, _ := message.Data.(cmn.OmciMessage)
Himani Chawla1472c682021-03-17 17:11:14 +0530390 am.handleOmciMessage(ctx, msg)
391 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 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 +0530393 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000394 case <-am.StopProcessingOmciMessages:
395 logger.Infow(ctx, "alarm-manager-stop-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawla1472c682021-03-17 17:11:14 +0530396 am.onuAlarmManagerLock.Lock()
397 am.processMessage = false
398 am.activeAlarms = nil
399 am.alarmBitMapDB = nil
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000400 am.alarmUploadNoOfCmdsOrMEs = 0
Himani Chawla1472c682021-03-17 17:11:14 +0530401 am.alarmUploadSeqNo = 0
402 am.onuAlarmManagerLock.Unlock()
403 return
404
Himani Chawlad3dac422021-03-13 02:31:31 +0530405 }
406 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530407}
408
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000409func (am *OnuAlarmManager) handleOmciMessage(ctx context.Context, msg cmn.OmciMessage) {
410 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530411 "msg-type": msg.OmciMsg.MessageType, "msg": msg})
412 switch msg.OmciMsg.MessageType {
413 case omci.GetAllAlarmsResponseType:
414 am.handleOmciGetAllAlarmsResponseMessage(ctx, msg)
415 case omci.GetAllAlarmsNextResponseType:
416 am.handleOmciGetAllAlarmNextResponseMessage(ctx, msg)
417 default:
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000418 logger.Warnw(ctx, "unknown-message-type", log.Fields{"device-id": am.deviceID, "msg-type": msg.OmciMsg.MessageType})
Himani Chawlad3dac422021-03-13 02:31:31 +0530419
420 }
421}
422
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000423func (am *OnuAlarmManager) handleOmciGetAllAlarmsResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530424 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsResponse)
425 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000426 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530427 return
428 }
429 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsResponse)
430 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000431 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530432 return
433 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 logger.Debugw(ctx, "get-all-alarm-response-data", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
435 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
436 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 +0530437 return
438 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000439 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000440 am.alarmUploadNoOfCmdsOrMEs = msgObj.NumberOfCommands
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000441 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530442 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000443 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
444 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 +0530445 }
446 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000447 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000448 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Himani Chawlad3dac422021-03-13 02:31:31 +0530449 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530450 am.resetAlarmSequence()
451 // Get a copy of the alarm bit map db.
452 for alarms, bitmap := range am.alarmBitMapDB {
453 am.oltDbCopy[alarms] = bitmap
454 }
455 am.onuAlarmManagerLock.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000457 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530458 // Transition to failure
459 go failureTransition()
460 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000461 } else if am.alarmUploadNoOfCmdsOrMEs == 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530462 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530463 am.resetAlarmSequence()
464 // Get a copy of the alarm bit map db.
465 for alarms, bitmap := range am.alarmBitMapDB {
466 am.oltDbCopy[alarms] = bitmap
467 }
468 am.onuAlarmManagerLock.Unlock()
469 if am.isAlarmDBDiffPresent(ctx) {
470 // transition to resync state
471 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000472 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
473 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 +0530474 }
475 }()
476 } else {
477 // Transition to sync state
478 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000479 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
480 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 +0530481 }
482 }()
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530483
Himani Chawlad3dac422021-03-13 02:31:31 +0530484 }
485 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000486 logger.Errorw(ctx, "invalid-number-of-commands-received", log.Fields{"device-id": am.deviceID,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000487 "upload-no-of-cmds": am.alarmUploadNoOfCmdsOrMEs, "upload-seq-no": am.alarmUploadSeqNo})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000488 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530489 go failureTransition()
490 }
491}
492
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493func (am *OnuAlarmManager) handleOmciGetAllAlarmNextResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530494 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsNextResponse)
495
496 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530498 return
499 }
500 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsNextResponse)
501 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530503 return
504 }
505 logger.Debugw(ctx, "get-all-alarms-next-response-data",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000506 log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawlad3dac422021-03-13 02:31:31 +0530507 meClassID := msgObj.AlarmEntityClass
508 meEntityID := msgObj.AlarmEntityInstance
509 meAlarmBitMap := msgObj.AlarmBitMap
510
511 am.onuAlarmManagerLock.Lock()
512 am.onuDBCopy[meAlarmKey{
513 classID: meClassID,
514 instanceID: meEntityID,
515 }] = meAlarmBitMap
516 am.onuAlarmManagerLock.Unlock()
517 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
519 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 +0530520 }
521 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000522 if msg.OmciMsg.DeviceIdentifier == omci.ExtendedIdent {
523 logger.Debugw(ctx, "get-all-alarms-next-response-additional-data",
524 log.Fields{"device-id": am.deviceID, "additional-data": msgObj.AdditionalAlarms})
525
526 for _, additionalAlarmReport := range msgObj.AdditionalAlarms {
527 meClassID := additionalAlarmReport.AlarmEntityClass
528 meEntityID := additionalAlarmReport.AlarmEntityInstance
529 meAlarmBitMap := additionalAlarmReport.AlarmBitMap
530
531 am.onuAlarmManagerLock.Lock()
532 am.onuDBCopy[meAlarmKey{
533 classID: meClassID,
534 instanceID: meEntityID,
535 }] = meAlarmBitMap
536 am.onuAlarmManagerLock.Unlock()
537
538 am.IncrementAlarmUploadSeqNo()
539 }
540 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000541 am.onuAlarmManagerLock.RLock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000542 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000543 am.onuAlarmManagerLock.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000544 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000545 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530546 // Transition to failure
547 go failureTransition()
548 } //TODO: needs to handle timeouts
549 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000550 am.onuAlarmManagerLock.RUnlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530551 if am.isAlarmDBDiffPresent(ctx) {
552 // transition to resync state
553 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000554 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
555 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 +0530556 }
557 }()
558 } else {
559 // Transition to sync state
560 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000561 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
562 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 +0530563 }
564 }()
565 }
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530566
Himani Chawlad3dac422021-03-13 02:31:31 +0530567 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530568}
569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570// StartOMCIAlarmMessageProcessing - TODO: add comment: add comment
571func (am *OnuAlarmManager) StartOMCIAlarmMessageProcessing(ctx context.Context) {
572 logger.Infow(ctx, "alarm-manager-start-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530573 am.onuAlarmManagerLock.Lock()
574 am.processMessage = true
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530575 if am.activeAlarms == nil {
576 am.activeAlarms = make(map[alarmInfo]struct{})
577 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530578 am.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000579 // when instantiating alarm manager it was too early, but now we can check for ONU's extended OMCI support
580 am.isExtendedOmci = am.pOnuDeviceEntry.GetPersIsExtOmciSupported()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530581 am.onuAlarmManagerLock.Unlock()
Himani Chawla1472c682021-03-17 17:11:14 +0530582 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
583
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
585 if err := am.AlarmSyncFsm.PFsm.Event(AsEvStart); err != nil {
586 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 +0530587 return
588 }
589 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 logger.Errorw(ctx, "wrong-state-of-alarm-sync-fsm-want-disabled", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current()),
591 "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530592 return
593 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594 logger.Debugw(ctx, "alarm-sync-fsm-started", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current())})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530595}
596
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597// HandleOmciAlarmNotificationMessage - TODO: add comment
598func (am *OnuAlarmManager) HandleOmciAlarmNotificationMessage(ctx context.Context, msg cmn.OmciMessage) {
599 logger.Debugw(ctx, "omci-alarm-notification-msg", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530600 "msg-type": msg.OmciMsg.MessageType})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530601
Himani Chawla7998aa92021-04-07 14:16:52 +0530602 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeAlarmNotification)
603 if msgLayer == nil {
604 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530606 return
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530607 }
Himani Chawla7998aa92021-04-07 14:16:52 +0530608 msgObj, msgOk := msgLayer.(*omci.AlarmNotificationMsg)
609 if !msgOk {
610 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530612 return
613 }
614 //Alarm Notification decoding at omci lib validates that the me class ID supports the
615 // alarm notifications.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 logger.Debugw(ctx, "alarm-notification-data-received", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawla7998aa92021-04-07 14:16:52 +0530617 if err := am.processAlarmData(ctx, msgObj); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530619 }
620
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530621}
622
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623func (am *OnuAlarmManager) processAlarmData(ctx context.Context, msg *omci.AlarmNotificationMsg) error {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530624 classID := msg.EntityClass
625 sequenceNo := msg.AlarmSequenceNumber
626 meInstance := msg.EntityInstance
627 alarmBitmap := msg.AlarmBitmap
628 logger.Debugw(ctx, "processing-alarm-data", log.Fields{"class-id": classID, "instance-id": meInstance,
629 "alarmBitMap": alarmBitmap, "sequence-no": sequenceNo})
Himani Chawla7998aa92021-04-07 14:16:52 +0530630 am.onuAlarmManagerLock.Lock()
631 defer am.onuAlarmManagerLock.Unlock()
632 if !am.processMessage {
633 logger.Warnw(ctx, "ignoring-alarm-notification-received-for-me-as-channel-for-processing-is-closed",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000634 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530635 return fmt.Errorf("alarm-manager-is-in-stopped-state")
636 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 if _, present := am.pOnuDeviceEntry.GetOnuDB().MeDb[classID][meInstance]; !present {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000638 logger.Errorw(ctx, "me-class-instance-not-present",
639 log.Fields{"class-id": classID, "instance-id": meInstance, "device-id": am.deviceID})
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530640 return fmt.Errorf("me-class-%d-instance-%d-not-present", classID, meInstance)
641 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530642 if sequenceNo > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 if am.AlarmSyncFsm.PFsm.Is(asStAuditing) || am.AlarmSyncFsm.PFsm.Is(asStResynchronizing) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530644 am.bufferedNotifications = append(am.bufferedNotifications, msg)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 logger.Debugw(ctx, "adding-notification-to-buffered-notification-list", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530646 "notification": msg})
647 return nil
Andrea Campanellace915292021-03-12 17:59:35 +0000648 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530649 am.incrementAlarmSequence()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000650 if sequenceNo != am.lastAlarmSequence && am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530651 // signal early audit, if no match(if we are reaching here it means that audit is not going on currently)
652 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
654 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 +0530655 }
656 }()
657 }
658 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530659 entity, omciErr := me.LoadManagedEntityDefinition(classID,
660 me.ParamData{EntityID: meInstance})
661 if omciErr.StatusCode() != me.Success {
662 //log error and return
663 logger.Error(ctx, "unable-to-get-managed-entity", log.Fields{"class-id": classID, "instance-id": meInstance})
664 return fmt.Errorf("unable-to-get-managed-entity-class-%d-instance-%d", classID, meInstance)
665 }
666 meAlarmMap := entity.GetAlarmMap()
667 if meAlarmMap == nil {
668 logger.Error(ctx, "unable-to-get-managed-entity-alarm-map", log.Fields{"class-id": classID, "instance-id": meInstance})
669 return fmt.Errorf("unable-to-get-managed-entity-alarm-map-%d-instance-%d", classID, meInstance)
670 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530671
672 am.alarmBitMapDB[meAlarmKey{
673 classID: classID,
674 instanceID: meInstance,
675 }] = alarmBitmap
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530676 // Loop over the supported alarm list for this me
677 for alarmNo := range meAlarmMap {
678 // Check if alarmNo was previously active in the alarms, if yes clear it and remove it from active alarms
679 _, exists := am.activeAlarms[alarmInfo{
680 classID: classID,
681 instanceID: meInstance,
682 alarmNo: alarmNo,
683 }]
684 if exists {
685 // Clear this alarm if It is cleared now, in that case IsAlarmClear would return true
686 cleared, err := msg.IsAlarmClear(alarmNo)
687 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000688 logger.Warnw(ctx, "unable-to-find-out-alarm-is-cleared", log.Fields{"device-id": am.deviceID,
689 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530690 return err
691 }
692 if cleared {
693 // Clear this alarm.
694 am.clearAlarm(ctx, classID, meInstance, alarmNo)
695 }
696 } else {
697 // If alarm entry was not present in the list of active alarms, we need to see if this alarm is now active
698 // or not, if yes then raise it.
699 raised, err := msg.IsAlarmActive(alarmNo)
700 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000701 logger.Warnw(ctx, "unable-to-find-out-alarm-is-raised", log.Fields{"device-id": am.deviceID,
702 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530703 return err
704 }
705 if raised {
706 am.raiseAlarm(ctx, classID, meInstance, alarmNo)
707 }
708 }
709 }
710 return nil
711}
712
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000713func (am *OnuAlarmManager) raiseAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530714 am.activeAlarms[alarmInfo{
715 classID: classID,
716 instanceID: instanceID,
717 alarmNo: alarm,
718 }] = struct{}{}
Himani Chawlad3dac422021-03-13 02:31:31 +0530719
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530720 go am.sendAlarm(ctx, classID, instanceID, alarm, true)
721}
722
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000723func (am *OnuAlarmManager) clearAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530724 go am.sendAlarm(ctx, classID, instanceID, alarm, false)
725 delete(am.activeAlarms, alarmInfo{
726 classID: classID,
727 instanceID: instanceID,
728 alarmNo: alarm,
729 })
Himani Chawlad3dac422021-03-13 02:31:31 +0530730 key := meAlarmKey{
731 classID: classID,
732 instanceID: instanceID,
733 }
734 if am.alarmBitMapDB[key] == [alarmBitMapSizeBytes]byte{0} {
735 delete(am.alarmBitMapDB, key)
736 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530737}
738
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000739func (am *OnuAlarmManager) getIntfIDAlarm(ctx context.Context, classID me.ClassID, instanceID uint16) *uint32 {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530740 var intfID *uint32
741 if classID == circuitPackClassID || classID == physicalPathTerminationPointEthernetUniClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000742 for _, uniPort := range *am.pDeviceHandler.GetUniEntityMap() {
743 if uniPort.EntityID == instanceID {
744 intfID = &uniPort.PortNo
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530745 return intfID
746 }
747 }
748 } else if classID == aniGClassID || classID == onuGClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000749 intfID = am.pDeviceHandler.GetPonPortNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530750 return intfID
751 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000752 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 +0530753 }
754 return nil
755}
756
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000757func (am *OnuAlarmManager) sendAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8, raised bool) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530758 context := make(map[string]string)
759 intfID := am.getIntfIDAlarm(ctx, classID, instanceID)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000760 onuID := am.deviceID
761 serialNo := am.pOnuDeviceEntry.GetPersSerialNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530762 if intfID == nil {
763 logger.Warn(ctx, "intf-id-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
764 return
765 }
766 context["onu-intf-id"] = fmt.Sprintf("%d", *intfID)
767 context["onu-id"] = onuID
768 context["onu-serial-number"] = serialNo
769
ozgecanetsia2f05ed32021-05-31 17:13:48 +0300770 raisedTimestamp := time.Now().Unix()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530771 eventDetails, err := am.getDeviceEventData(ctx, classID, alarm)
772 if err != nil {
773 logger.Warn(ctx, "event-details-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
774 return
775 }
776 suffixDesc := "Raised"
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300777 clearOrRaiseEvent := "RAISE_EVENT"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530778 if !raised {
779 suffixDesc = "Cleared"
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300780 clearOrRaiseEvent = "CLEAR_EVENT"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530781 }
782 deviceEvent := &voltha.DeviceEvent{
783 ResourceId: onuID,
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300784 DeviceEventName: fmt.Sprintf("%s_%s", eventDetails.EventName, clearOrRaiseEvent),
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530785 Description: fmt.Sprintf("%s Event - %s - %s", eventDetails.EventDescription, eventDetails.EventName,
786 suffixDesc),
787 Context: context,
788 }
789 _ = am.eventProxy.SendDeviceEvent(ctx, deviceEvent, eventDetails.EventCategory, eventDetails.EventSubCategory,
790 raisedTimestamp)
791}
Himani Chawlad3dac422021-03-13 02:31:31 +0530792
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530794 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
795}
796
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000797func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530798 //alarm sequence number wraps from 255 to 1.
799 if am.lastAlarmSequence == 255 {
800 am.lastAlarmSequence = 1
801 } else {
802 am.lastAlarmSequence++
803 }
804}
805
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530807 am.lastAlarmSequence = 0
808}
809
810// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530812 // flush alarm sync channel
813 select {
814 case <-am.eventChannel:
815 logger.Debug(ctx, "flushed-alarm-sync-channel")
816 default:
817 }
818 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530820 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
821 default:
822 }
823}
824
825// getDeviceEventData returns the event data for a device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530827 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
828 return onuEventDetails, nil
829 }
830 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
831}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000832
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530833// ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000834func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000835 am.onuAlarmManagerLock.Lock()
836 am.alarmUploadSeqNo = 0
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000837 am.alarmUploadNoOfCmdsOrMEs = 0
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000838 am.onuAlarmManagerLock.Unlock()
839}
840
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530841// IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000843 am.onuAlarmManagerLock.Lock()
844 am.alarmUploadSeqNo++
845 am.onuAlarmManagerLock.Unlock()
846}
847
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530848// GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000849func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000850 am.onuAlarmManagerLock.RLock()
851 value := am.alarmUploadSeqNo
852 am.onuAlarmManagerLock.RUnlock()
853 return value
854}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530856// GetAlarmMgrEventChannel gets alarm manager event channel
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
858 return am.eventChannel
859}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000860
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530861// GetOnuActiveAlarms - Fetch the Active Alarms on demand
862func (am *OnuAlarmManager) GetOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
863
864 am.onuAlarmRequestLock.Lock()
865 defer am.onuAlarmRequestLock.Unlock()
866
867 resp := extension.SingleGetValueResponse{
868 Response: &extension.GetValueResponse{
869 Status: extension.GetValueResponse_OK,
870 Response: &extension.GetValueResponse_OnuActiveAlarms{
871 OnuActiveAlarms: &extension.GetOnuOmciActiveAlarmsResponse{},
872 },
873 },
874 }
875
876 logger.Debugw(ctx, "Requesting to start audit on demand ", log.Fields{"device-id": am.deviceID})
877 am.isAsyncAlarmRequest = true
878
879 am.AsyncAlarmsCommChan <- struct{}{}
880
881 select {
882 case <-time.After(10 * time.Second): //the time to wait needs further discussion.
883 logger.Errorw(ctx, "Couldn't get the Alarms with in 10 seconds stipulated time frame ", log.Fields{"device-id": am.deviceID})
884 am.isAsyncAlarmRequest = false
885
886 case <-am.AsyncAlarmsCommChan:
887 logger.Debugw(ctx, "Received response for the alarm audit ", log.Fields{"device-id": am.deviceID})
888
889 }
890
891 for activeAlarm := range am.activeAlarms {
892
893 onuEventDetails := am.onuEventsList[onuDevice{classID: activeAlarm.classID, alarmno: activeAlarm.alarmNo}]
894 activeAlarmData := extension.AlarmData{}
895 activeAlarmData.ClassId = uint32(activeAlarm.classID)
896 activeAlarmData.InstanceId = uint32(activeAlarm.instanceID)
897 activeAlarmData.Name = onuEventDetails.EventName
898 activeAlarmData.Description = onuEventDetails.EventDescription
899
900 resp.Response.GetOnuActiveAlarms().ActiveAlarms = append(resp.Response.GetOnuActiveAlarms().ActiveAlarms, &activeAlarmData)
901
902 }
903
904 return &resp
905}
906
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000907// PrepareForGarbageCollection - remove references to prepare for garbage collection
908func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
909 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
910 am.pDeviceHandler = nil
911 am.pOnuDeviceEntry = nil
912}