blob: 159736b843157aca14f3c440c131d85884ec52a8 [file] [log] [blame]
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301/*
2 * Copyright 2021-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package almgr provides the utilities for managing alarm notifications
18package 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"
khenaidoo7d3c5582021-08-11 18:09:44 -040034 "github.com/opencord/voltha-protos/v5/go/voltha"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053035)
36
37const (
38 circuitPackClassID = me.CircuitPackClassID
39 physicalPathTerminationPointEthernetUniClassID = me.PhysicalPathTerminationPointEthernetUniClassID
40 onuGClassID = me.OnuGClassID
41 aniGClassID = me.AniGClassID
Himani Chawlad3dac422021-03-13 02:31:31 +053042 defaultTimeoutDelay = 10
43 alarmBitMapSizeBytes = 28
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053044)
45
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000046// events of alarm sync FSM
Himani Chawlad3dac422021-03-13 02:31:31 +053047const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000048 AsEvStart = "AsEvStart"
49 AsEvStop = "AsEvStop"
50 AsEvAudit = "AsEvAudit"
51 AsEvSync = "AsEvSync"
52 AsEvSuccess = "AsEvSuccess"
53 AsEvFailure = "AsEvFailure"
54 AsEvResync = "AsEvResync"
Himani Chawlad3dac422021-03-13 02:31:31 +053055)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000056
57// states of alarm sync FSM
Himani Chawlad3dac422021-03-13 02:31:31 +053058const (
Himani Chawlad3dac422021-03-13 02:31:31 +053059 asStStarting = "asStStarting"
60 asStDisabled = "asStDisabled"
61 asStInSync = "asStInSync"
62 asStAuditing = "asStAuditing"
63 asStResynchronizing = "asStResynchronizing"
64 asStIdle = "asStIdle"
65)
66
67//const cAsFsmIdleState = asStIdle not using idle state currently
68
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053069type alarmInfo struct {
70 classID me.ClassID
71 instanceID uint16
72 alarmNo uint8
73}
74
75type alarms map[alarmInfo]struct{}
76
Himani Chawlad3dac422021-03-13 02:31:31 +053077type meAlarmKey struct {
78 classID me.ClassID
79 instanceID uint16
80}
81
82type alarmBitMapDB map[meAlarmKey][alarmBitMapSizeBytes]byte
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053083
84type onuDevice struct {
85 classID me.ClassID
86 alarmno uint8
87}
88type onuDeviceEvent struct {
89 EventName string
90 EventCategory eventif.EventCategory
91 EventSubCategory eventif.EventSubCategory
92 EventDescription string
93}
94
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000095// OnuAlarmManager holds alarm manager related data
96type OnuAlarmManager struct {
97 deviceID string
98 pDeviceHandler cmn.IdeviceHandler
99 pOnuDeviceEntry cmn.IonuDeviceEntry
100 eventProxy eventif.EventProxy
101 StopProcessingOmciMessages chan bool
102 eventChannel chan cmn.Message
103 onuAlarmManagerLock sync.RWMutex
104 processMessage bool
105 activeAlarms alarms
106 alarmBitMapDB alarmBitMapDB
107 onuEventsList map[onuDevice]onuDeviceEvent
108 lastAlarmSequence uint8
109 AlarmSyncFsm *cmn.AdapterFsm
110 oltDbCopy alarmBitMapDB
111 onuDBCopy alarmBitMapDB
112 bufferedNotifications []*omci.AlarmNotificationMsg
113 alarmUploadSeqNo uint16
114 alarmUploadNoOfCmds uint16
115 StopAlarmAuditTimer chan struct{}
116}
117
118// NewAlarmManager - TODO: add comment
119func NewAlarmManager(ctx context.Context, dh cmn.IdeviceHandler, onuDev cmn.IonuDeviceEntry) *OnuAlarmManager {
120 var alarmManager OnuAlarmManager
121 alarmManager.deviceID = dh.GetDeviceID()
122 logger.Debugw(ctx, "init-alarm-manager", log.Fields{"device-id": alarmManager.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530123 alarmManager.pDeviceHandler = dh
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000124 alarmManager.pOnuDeviceEntry = onuDev
125 alarmManager.eventProxy = dh.GetEventProxy() // Or event proxy should be on cluster address ??
126 alarmManager.eventChannel = make(chan cmn.Message)
127 alarmManager.StopProcessingOmciMessages = make(chan bool)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530128 alarmManager.processMessage = false
129 alarmManager.activeAlarms = make(map[alarmInfo]struct{})
Himani Chawlad3dac422021-03-13 02:31:31 +0530130 alarmManager.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000131 alarmManager.StopAlarmAuditTimer = make(chan struct{})
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530132 alarmManager.onuEventsList = map[onuDevice]onuDeviceEvent{
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530133 {classID: circuitPackClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
134 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
135 {classID: circuitPackClassID, alarmno: 2}: {EventName: "ONU_SELF_TEST_FAIL",
136 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
137 {classID: circuitPackClassID, alarmno: 3}: {EventName: "ONU_LASER_EOL",
138 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser EOL"},
139 {classID: circuitPackClassID, alarmno: 4}: {EventName: "ONU_TEMP_YELLOW",
140 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
141 {classID: circuitPackClassID, alarmno: 5}: {EventName: "ONU_TEMP_RED",
142 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
143 {classID: physicalPathTerminationPointEthernetUniClassID, alarmno: 0}: {EventName: "ONU_Ethernet_UNI", EventCategory: voltha.EventCategory_EQUIPMENT,
144 EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "LAN Loss Of Signal"},
145 {classID: onuGClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
146 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
147 {classID: onuGClassID, alarmno: 6}: {EventName: "ONU_SELF_TEST_FAIL",
148 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
149 {classID: onuGClassID, alarmno: 7}: {EventName: "ONU_DYING_GASP",
150 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu DYING_GASP"},
151 {classID: onuGClassID, alarmno: 8}: {EventName: "ONU_TEMP_YELLOW",
152 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
153 {classID: onuGClassID, alarmno: 9}: {EventName: "ONU_TEMP_RED",
154 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
155 {classID: onuGClassID, alarmno: 10}: {EventName: "ONU_VOLTAGE_YELLOW",
156 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage yellow"},
157 {classID: onuGClassID, alarmno: 11}: {EventName: "ONU_VOLTAGE_RED",
158 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage red"},
159 {classID: aniGClassID, alarmno: 0}: {EventName: "ONU_LOW_RX_OPTICAL",
160 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low rx optical power"},
161 {classID: aniGClassID, alarmno: 1}: {EventName: "ONU_HIGH_RX_OPTICAL",
162 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high rx optical power"},
163 {classID: aniGClassID, alarmno: 4}: {EventName: "ONU_LOW_TX_OPTICAL",
164 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low tx optical power"},
165 {classID: aniGClassID, alarmno: 5}: {EventName: "ONU_HIGH_TX_OPTICAL",
166 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high tx optical power"},
167 {classID: aniGClassID, alarmno: 6}: {EventName: "ONU_LASER_BIAS_CURRENT",
168 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser bias current"},
169 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000170 alarmManager.AlarmSyncFsm = cmn.NewAdapterFsm("AlarmSync", alarmManager.deviceID, alarmManager.eventChannel)
171 alarmManager.AlarmSyncFsm.PFsm = fsm.NewFSM(
Himani Chawlad3dac422021-03-13 02:31:31 +0530172 asStDisabled,
173 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000174 {Name: AsEvStart, Src: []string{asStDisabled}, Dst: asStStarting},
175 {Name: AsEvAudit, Src: []string{asStStarting, asStInSync}, Dst: asStAuditing},
176 {Name: AsEvSync, Src: []string{asStStarting}, Dst: asStInSync},
177 {Name: AsEvSuccess, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStInSync},
178 {Name: AsEvFailure, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStAuditing},
179 {Name: AsEvResync, Src: []string{asStAuditing}, Dst: asStResynchronizing},
180 {Name: AsEvStop, Src: []string{asStDisabled, asStStarting, asStAuditing, asStInSync, asStIdle, asStResynchronizing}, Dst: asStDisabled},
Himani Chawlad3dac422021-03-13 02:31:31 +0530181 },
182 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000183 "enter_state": func(e *fsm.Event) { alarmManager.AlarmSyncFsm.LogFsmStateChange(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530184 "enter_" + asStStarting: func(e *fsm.Event) { alarmManager.asFsmStarting(ctx, e) },
185 "enter_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmAuditing(ctx, e) },
186 "enter_" + asStInSync: func(e *fsm.Event) { alarmManager.asFsmInSync(ctx, e) },
187 "enter_" + asStResynchronizing: func(e *fsm.Event) { alarmManager.asFsmResynchronizing(ctx, e) },
188 },
189 )
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530190 return &alarmManager
191}
192
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000193func (am *OnuAlarmManager) asFsmStarting(ctx context.Context, e *fsm.Event) {
194 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 +0530195 go am.processAlarmSyncMessages(ctx)
196 // Start the first audit, if audit interval configured, else reach the sync state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000197 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530198 select {
199 //Transition into auditing state, using a very shorter timeout delay here, hence it is the first audit
200 case <-time.After(defaultTimeoutDelay * time.Second):
201 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000202 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
203 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 +0530204 }
205 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000206 case <-am.StopAlarmAuditTimer:
207 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530208 return
209 }
210 } else {
211 // Transition into sync state directly.
212 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000213 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSync); err != nil {
214 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 +0530215 }
216 }()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530217 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530218}
219
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000220func (am *OnuAlarmManager) asFsmAuditing(ctx context.Context, e *fsm.Event) {
221 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 +0530222 // Always reset the buffered notifications and db copies before starting the audit
223 am.onuAlarmManagerLock.Lock()
224 am.bufferedNotifications = make([]*omci.AlarmNotificationMsg, 0)
225 am.oltDbCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
226 am.onuDBCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
227 am.onuAlarmManagerLock.Unlock()
228 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000229 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
230 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 +0530231 }
232 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000233 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarm(log.WithSpanFromContext(context.TODO(), ctx), 0,
234 am.pDeviceHandler.GetOmciTimeout(), true); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530235 // Transition to failure so that alarm sync can be restarted again
236 go failureTransition()
237 }
238}
239
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000240func (am *OnuAlarmManager) asFsmResynchronizing(ctx context.Context, e *fsm.Event) {
241 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530242 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000243 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
244 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 +0530245 }
246 }
247 // See if there is any onu only diff, meaning the class and entity is only in onu DB
248 for alarm := range am.onuDBCopy {
249 if _, exists := am.oltDbCopy[meAlarmKey{
250 classID: alarm.classID,
251 instanceID: alarm.instanceID,
252 }]; !exists {
253 // We need to raise all such alarms as OLT wont have received notification for these alarms
254 omciAlarmMessage := &omci.AlarmNotificationMsg{
255 MeBasePacket: omci.MeBasePacket{
256 EntityClass: alarm.classID,
257 EntityInstance: alarm.instanceID,
258 },
259 AlarmBitmap: am.onuDBCopy[alarm],
260 }
261 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000262 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530263 // Transition to failure.
264 go failureTransition()
265 return
266 }
267 }
268 }
269 // See if there is any olt only diff, meaning the class and entity is only in olt DB
270 for alarm := range am.oltDbCopy {
271 if _, exists := am.onuDBCopy[meAlarmKey{
272 classID: alarm.classID,
273 instanceID: alarm.instanceID,
274 }]; !exists {
275 // We need to clear all such alarms as OLT might have stale data and the alarms are already cleared.
276 omciAlarmMessage := &omci.AlarmNotificationMsg{
277 MeBasePacket: omci.MeBasePacket{
278 EntityClass: alarm.classID,
279 EntityInstance: alarm.instanceID,
280 },
281 AlarmBitmap: am.oltDbCopy[alarm],
282 }
283 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000284 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530285 // Transition to failure
286 go failureTransition()
287 return
288 }
289 }
290 }
291 // See if there is any attribute difference
292 for alarm := range am.onuDBCopy {
293 if _, exists := am.oltDbCopy[alarm]; exists {
294 if am.onuDBCopy[alarm] != am.oltDbCopy[alarm] {
295 omciAlarmMessage := &omci.AlarmNotificationMsg{
296 MeBasePacket: omci.MeBasePacket{
297 EntityClass: alarm.classID,
298 EntityInstance: alarm.instanceID,
299 },
300 AlarmBitmap: am.onuDBCopy[alarm],
301 }
302 // We will assume that onudb is correct always in this case and process the changed bitmap.
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 }
312 // Send the buffered notifications if no failure.
313 for _, notif := range am.bufferedNotifications {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000314 logger.Debugw(ctx, "processing-buffered-alarm-notification", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530315 "notification": notif})
316 if err := am.processAlarmData(ctx, notif); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000317 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530318 go failureTransition()
319 }
320 }
321 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000322 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
323 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 +0530324 }
325 }()
326}
327
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000328func (am *OnuAlarmManager) asFsmInSync(ctx context.Context, e *fsm.Event) {
329 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
330 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530331 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000332 case <-time.After(am.pDeviceHandler.GetAlarmAuditInterval()):
Himani Chawlad3dac422021-03-13 02:31:31 +0530333 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000334 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
335 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 +0530336 }
337 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338 case <-am.StopAlarmAuditTimer:
339 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530340 return
341 }
342 }
343}
344
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345func (am *OnuAlarmManager) processAlarmSyncMessages(ctx context.Context) {
346 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 +0530347 for {
Himani Chawla1472c682021-03-17 17:11:14 +0530348 select {
349 case message, ok := <-am.eventChannel:
350 if !ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000351 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 +0530352 continue
353 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000354 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530355
Himani Chawla1472c682021-03-17 17:11:14 +0530356 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000357 case cmn.OMCI:
358 msg, _ := message.Data.(cmn.OmciMessage)
Himani Chawla1472c682021-03-17 17:11:14 +0530359 am.handleOmciMessage(ctx, msg)
360 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 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 +0530362 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000363 case <-am.StopProcessingOmciMessages:
364 logger.Infow(ctx, "alarm-manager-stop-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawla1472c682021-03-17 17:11:14 +0530365 am.onuAlarmManagerLock.Lock()
366 am.processMessage = false
367 am.activeAlarms = nil
368 am.alarmBitMapDB = nil
369 am.alarmUploadNoOfCmds = 0
370 am.alarmUploadSeqNo = 0
371 am.onuAlarmManagerLock.Unlock()
372 return
373
Himani Chawlad3dac422021-03-13 02:31:31 +0530374 }
375 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530376}
377
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378func (am *OnuAlarmManager) handleOmciMessage(ctx context.Context, msg cmn.OmciMessage) {
379 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530380 "msg-type": msg.OmciMsg.MessageType, "msg": msg})
381 switch msg.OmciMsg.MessageType {
382 case omci.GetAllAlarmsResponseType:
383 am.handleOmciGetAllAlarmsResponseMessage(ctx, msg)
384 case omci.GetAllAlarmsNextResponseType:
385 am.handleOmciGetAllAlarmNextResponseMessage(ctx, msg)
386 default:
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000387 logger.Warnw(ctx, "unknown-message-type", log.Fields{"device-id": am.deviceID, "msg-type": msg.OmciMsg.MessageType})
Himani Chawlad3dac422021-03-13 02:31:31 +0530388
389 }
390}
391
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392func (am *OnuAlarmManager) handleOmciGetAllAlarmsResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530393 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsResponse)
394 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530396 return
397 }
398 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsResponse)
399 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530401 return
402 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000403 logger.Debugw(ctx, "get-all-alarm-response-data", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
404 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
405 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 +0530406 return
407 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000408 am.onuAlarmManagerLock.Lock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530409 am.alarmUploadNoOfCmds = msgObj.NumberOfCommands
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000410 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530411 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
413 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 +0530414 }
415 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000416 am.onuAlarmManagerLock.Lock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530417 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmds {
418 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530419 am.resetAlarmSequence()
420 // Get a copy of the alarm bit map db.
421 for alarms, bitmap := range am.alarmBitMapDB {
422 am.oltDbCopy[alarms] = bitmap
423 }
424 am.onuAlarmManagerLock.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000425 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
426 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530427 // Transition to failure
428 go failureTransition()
429 }
430 } else if am.alarmUploadNoOfCmds == 0 {
431 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530432 am.resetAlarmSequence()
433 // Get a copy of the alarm bit map db.
434 for alarms, bitmap := range am.alarmBitMapDB {
435 am.oltDbCopy[alarms] = bitmap
436 }
437 am.onuAlarmManagerLock.Unlock()
438 if am.isAlarmDBDiffPresent(ctx) {
439 // transition to resync state
440 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
442 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 +0530443 }
444 }()
445 } else {
446 // Transition to sync state
447 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000448 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
449 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 +0530450 }
451 }()
452 }
453 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000454 logger.Errorw(ctx, "invalid-number-of-commands-received", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530455 "upload-no-of-cmds": am.alarmUploadNoOfCmds, "upload-seq-no": am.alarmUploadSeqNo})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000456 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530457 go failureTransition()
458 }
459}
460
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000461func (am *OnuAlarmManager) handleOmciGetAllAlarmNextResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530462 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsNextResponse)
463
464 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000465 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530466 return
467 }
468 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsNextResponse)
469 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000470 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530471 return
472 }
473 logger.Debugw(ctx, "get-all-alarms-next-response-data",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000474 log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawlad3dac422021-03-13 02:31:31 +0530475 meClassID := msgObj.AlarmEntityClass
476 meEntityID := msgObj.AlarmEntityInstance
477 meAlarmBitMap := msgObj.AlarmBitMap
478
479 am.onuAlarmManagerLock.Lock()
480 am.onuDBCopy[meAlarmKey{
481 classID: meClassID,
482 instanceID: meEntityID,
483 }] = meAlarmBitMap
484 am.onuAlarmManagerLock.Unlock()
485 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000486 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
487 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 +0530488 }
489 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000490 am.onuAlarmManagerLock.RLock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530491 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmds {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000492 am.onuAlarmManagerLock.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
494 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530495 // Transition to failure
496 go failureTransition()
497 } //TODO: needs to handle timeouts
498 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000499 am.onuAlarmManagerLock.RUnlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530500 if am.isAlarmDBDiffPresent(ctx) {
501 // transition to resync state
502 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000503 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
504 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 +0530505 }
506 }()
507 } else {
508 // Transition to sync state
509 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000510 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
511 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 +0530512 }
513 }()
514 }
515 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530516}
517
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518// StartOMCIAlarmMessageProcessing - TODO: add comment: add comment
519func (am *OnuAlarmManager) StartOMCIAlarmMessageProcessing(ctx context.Context) {
520 logger.Infow(ctx, "alarm-manager-start-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530521 am.onuAlarmManagerLock.Lock()
522 am.processMessage = true
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530523 if am.activeAlarms == nil {
524 am.activeAlarms = make(map[alarmInfo]struct{})
525 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530526 am.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530527 am.onuAlarmManagerLock.Unlock()
Himani Chawla1472c682021-03-17 17:11:14 +0530528 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
529
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000530 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
531 if err := am.AlarmSyncFsm.PFsm.Event(AsEvStart); err != nil {
532 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 +0530533 return
534 }
535 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536 logger.Errorw(ctx, "wrong-state-of-alarm-sync-fsm-want-disabled", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current()),
537 "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530538 return
539 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 logger.Debugw(ctx, "alarm-sync-fsm-started", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current())})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530541}
542
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543// HandleOmciAlarmNotificationMessage - TODO: add comment
544func (am *OnuAlarmManager) HandleOmciAlarmNotificationMessage(ctx context.Context, msg cmn.OmciMessage) {
545 logger.Debugw(ctx, "omci-alarm-notification-msg", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530546 "msg-type": msg.OmciMsg.MessageType})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530547
Himani Chawla7998aa92021-04-07 14:16:52 +0530548 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeAlarmNotification)
549 if msgLayer == nil {
550 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000551 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530552 return
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530553 }
Himani Chawla7998aa92021-04-07 14:16:52 +0530554 msgObj, msgOk := msgLayer.(*omci.AlarmNotificationMsg)
555 if !msgOk {
556 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530558 return
559 }
560 //Alarm Notification decoding at omci lib validates that the me class ID supports the
561 // alarm notifications.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 logger.Debugw(ctx, "alarm-notification-data-received", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawla7998aa92021-04-07 14:16:52 +0530563 if err := am.processAlarmData(ctx, msgObj); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530565 }
566
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530567}
568
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569func (am *OnuAlarmManager) processAlarmData(ctx context.Context, msg *omci.AlarmNotificationMsg) error {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530570 classID := msg.EntityClass
571 sequenceNo := msg.AlarmSequenceNumber
572 meInstance := msg.EntityInstance
573 alarmBitmap := msg.AlarmBitmap
574 logger.Debugw(ctx, "processing-alarm-data", log.Fields{"class-id": classID, "instance-id": meInstance,
575 "alarmBitMap": alarmBitmap, "sequence-no": sequenceNo})
Himani Chawla7998aa92021-04-07 14:16:52 +0530576 am.onuAlarmManagerLock.Lock()
577 defer am.onuAlarmManagerLock.Unlock()
578 if !am.processMessage {
579 logger.Warnw(ctx, "ignoring-alarm-notification-received-for-me-as-channel-for-processing-is-closed",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530581 return fmt.Errorf("alarm-manager-is-in-stopped-state")
582 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 if _, present := am.pOnuDeviceEntry.GetOnuDB().MeDb[classID][meInstance]; !present {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000584 logger.Errorw(ctx, "me-class-instance-not-present",
585 log.Fields{"class-id": classID, "instance-id": meInstance, "device-id": am.deviceID})
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530586 return fmt.Errorf("me-class-%d-instance-%d-not-present", classID, meInstance)
587 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530588 if sequenceNo > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000589 if am.AlarmSyncFsm.PFsm.Is(asStAuditing) || am.AlarmSyncFsm.PFsm.Is(asStResynchronizing) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530590 am.bufferedNotifications = append(am.bufferedNotifications, msg)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 logger.Debugw(ctx, "adding-notification-to-buffered-notification-list", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530592 "notification": msg})
593 return nil
Andrea Campanellace915292021-03-12 17:59:35 +0000594 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530595 am.incrementAlarmSequence()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000596 if sequenceNo != am.lastAlarmSequence && am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530597 // signal early audit, if no match(if we are reaching here it means that audit is not going on currently)
598 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
600 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 +0530601 }
602 }()
603 }
604 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530605 entity, omciErr := me.LoadManagedEntityDefinition(classID,
606 me.ParamData{EntityID: meInstance})
607 if omciErr.StatusCode() != me.Success {
608 //log error and return
609 logger.Error(ctx, "unable-to-get-managed-entity", log.Fields{"class-id": classID, "instance-id": meInstance})
610 return fmt.Errorf("unable-to-get-managed-entity-class-%d-instance-%d", classID, meInstance)
611 }
612 meAlarmMap := entity.GetAlarmMap()
613 if meAlarmMap == nil {
614 logger.Error(ctx, "unable-to-get-managed-entity-alarm-map", log.Fields{"class-id": classID, "instance-id": meInstance})
615 return fmt.Errorf("unable-to-get-managed-entity-alarm-map-%d-instance-%d", classID, meInstance)
616 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530617
618 am.alarmBitMapDB[meAlarmKey{
619 classID: classID,
620 instanceID: meInstance,
621 }] = alarmBitmap
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530622 // Loop over the supported alarm list for this me
623 for alarmNo := range meAlarmMap {
624 // Check if alarmNo was previously active in the alarms, if yes clear it and remove it from active alarms
625 _, exists := am.activeAlarms[alarmInfo{
626 classID: classID,
627 instanceID: meInstance,
628 alarmNo: alarmNo,
629 }]
630 if exists {
631 // Clear this alarm if It is cleared now, in that case IsAlarmClear would return true
632 cleared, err := msg.IsAlarmClear(alarmNo)
633 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000634 logger.Warnw(ctx, "unable-to-find-out-alarm-is-cleared", log.Fields{"device-id": am.deviceID,
635 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530636 return err
637 }
638 if cleared {
639 // Clear this alarm.
640 am.clearAlarm(ctx, classID, meInstance, alarmNo)
641 }
642 } else {
643 // If alarm entry was not present in the list of active alarms, we need to see if this alarm is now active
644 // or not, if yes then raise it.
645 raised, err := msg.IsAlarmActive(alarmNo)
646 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000647 logger.Warnw(ctx, "unable-to-find-out-alarm-is-raised", log.Fields{"device-id": am.deviceID,
648 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530649 return err
650 }
651 if raised {
652 am.raiseAlarm(ctx, classID, meInstance, alarmNo)
653 }
654 }
655 }
656 return nil
657}
658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659func (am *OnuAlarmManager) raiseAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530660 am.activeAlarms[alarmInfo{
661 classID: classID,
662 instanceID: instanceID,
663 alarmNo: alarm,
664 }] = struct{}{}
Himani Chawlad3dac422021-03-13 02:31:31 +0530665
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530666 go am.sendAlarm(ctx, classID, instanceID, alarm, true)
667}
668
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000669func (am *OnuAlarmManager) clearAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530670 go am.sendAlarm(ctx, classID, instanceID, alarm, false)
671 delete(am.activeAlarms, alarmInfo{
672 classID: classID,
673 instanceID: instanceID,
674 alarmNo: alarm,
675 })
Himani Chawlad3dac422021-03-13 02:31:31 +0530676 key := meAlarmKey{
677 classID: classID,
678 instanceID: instanceID,
679 }
680 if am.alarmBitMapDB[key] == [alarmBitMapSizeBytes]byte{0} {
681 delete(am.alarmBitMapDB, key)
682 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530683}
684
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000685func (am *OnuAlarmManager) getIntfIDAlarm(ctx context.Context, classID me.ClassID, instanceID uint16) *uint32 {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530686 var intfID *uint32
687 if classID == circuitPackClassID || classID == physicalPathTerminationPointEthernetUniClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000688 for _, uniPort := range *am.pDeviceHandler.GetUniEntityMap() {
689 if uniPort.EntityID == instanceID {
690 intfID = &uniPort.PortNo
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530691 return intfID
692 }
693 }
694 } else if classID == aniGClassID || classID == onuGClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000695 intfID = am.pDeviceHandler.GetPonPortNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530696 return intfID
697 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000698 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 +0530699 }
700 return nil
701}
702
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000703func (am *OnuAlarmManager) sendAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8, raised bool) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530704 context := make(map[string]string)
705 intfID := am.getIntfIDAlarm(ctx, classID, instanceID)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000706 onuID := am.deviceID
707 serialNo := am.pOnuDeviceEntry.GetPersSerialNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530708 if intfID == nil {
709 logger.Warn(ctx, "intf-id-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
710 return
711 }
712 context["onu-intf-id"] = fmt.Sprintf("%d", *intfID)
713 context["onu-id"] = onuID
714 context["onu-serial-number"] = serialNo
715
ozgecanetsia2f05ed32021-05-31 17:13:48 +0300716 raisedTimestamp := time.Now().Unix()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530717 eventDetails, err := am.getDeviceEventData(ctx, classID, alarm)
718 if err != nil {
719 logger.Warn(ctx, "event-details-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
720 return
721 }
722 suffixDesc := "Raised"
723 if !raised {
724 suffixDesc = "Cleared"
725 }
726 deviceEvent := &voltha.DeviceEvent{
727 ResourceId: onuID,
728 DeviceEventName: fmt.Sprintf("%s_RAISE_EVENT", eventDetails.EventName),
729 Description: fmt.Sprintf("%s Event - %s - %s", eventDetails.EventDescription, eventDetails.EventName,
730 suffixDesc),
731 Context: context,
732 }
733 _ = am.eventProxy.SendDeviceEvent(ctx, deviceEvent, eventDetails.EventCategory, eventDetails.EventSubCategory,
734 raisedTimestamp)
735}
Himani Chawlad3dac422021-03-13 02:31:31 +0530736
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530738 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
739}
740
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000741func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530742 //alarm sequence number wraps from 255 to 1.
743 if am.lastAlarmSequence == 255 {
744 am.lastAlarmSequence = 1
745 } else {
746 am.lastAlarmSequence++
747 }
748}
749
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000750func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530751 am.lastAlarmSequence = 0
752}
753
754// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000755func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530756 // flush alarm sync channel
757 select {
758 case <-am.eventChannel:
759 logger.Debug(ctx, "flushed-alarm-sync-channel")
760 default:
761 }
762 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530764 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
765 default:
766 }
767}
768
769// getDeviceEventData returns the event data for a device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000770func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530771 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
772 return onuEventDetails, nil
773 }
774 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
775}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000776
777//ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000778func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000779 am.onuAlarmManagerLock.Lock()
780 am.alarmUploadSeqNo = 0
781 am.alarmUploadNoOfCmds = 0
782 am.onuAlarmManagerLock.Unlock()
783}
784
785//IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000786func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000787 am.onuAlarmManagerLock.Lock()
788 am.alarmUploadSeqNo++
789 am.onuAlarmManagerLock.Unlock()
790}
791
792//GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000793func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000794 am.onuAlarmManagerLock.RLock()
795 value := am.alarmUploadSeqNo
796 am.onuAlarmManagerLock.RUnlock()
797 return value
798}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000799
800//GetAlarmMgrEventChannel gets alarm manager event channel
801func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
802 return am.eventChannel
803}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000804
805// PrepareForGarbageCollection - remove references to prepare for garbage collection
806func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
807 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
808 am.pDeviceHandler = nil
809 am.pOnuDeviceEntry = nil
810}