blob: 69ae8627277b622c22b9f5c0fc8dea5645e45ada [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:
387 logger.Warnw(ctx, "unknown-message-type", log.Fields{"msg-type": msg.OmciMsg.MessageType})
388
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 {
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530584 logger.Errorw(ctx, "me-class-instance-not-present", log.Fields{"class-id": classID, "instance-id": meInstance})
585 return fmt.Errorf("me-class-%d-instance-%d-not-present", classID, meInstance)
586 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530587 if sequenceNo > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 if am.AlarmSyncFsm.PFsm.Is(asStAuditing) || am.AlarmSyncFsm.PFsm.Is(asStResynchronizing) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530589 am.bufferedNotifications = append(am.bufferedNotifications, msg)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 logger.Debugw(ctx, "adding-notification-to-buffered-notification-list", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530591 "notification": msg})
592 return nil
Andrea Campanellace915292021-03-12 17:59:35 +0000593 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530594 am.incrementAlarmSequence()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 if sequenceNo != am.lastAlarmSequence && am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530596 // signal early audit, if no match(if we are reaching here it means that audit is not going on currently)
597 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
599 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 +0530600 }
601 }()
602 }
603 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530604 entity, omciErr := me.LoadManagedEntityDefinition(classID,
605 me.ParamData{EntityID: meInstance})
606 if omciErr.StatusCode() != me.Success {
607 //log error and return
608 logger.Error(ctx, "unable-to-get-managed-entity", log.Fields{"class-id": classID, "instance-id": meInstance})
609 return fmt.Errorf("unable-to-get-managed-entity-class-%d-instance-%d", classID, meInstance)
610 }
611 meAlarmMap := entity.GetAlarmMap()
612 if meAlarmMap == nil {
613 logger.Error(ctx, "unable-to-get-managed-entity-alarm-map", log.Fields{"class-id": classID, "instance-id": meInstance})
614 return fmt.Errorf("unable-to-get-managed-entity-alarm-map-%d-instance-%d", classID, meInstance)
615 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530616
617 am.alarmBitMapDB[meAlarmKey{
618 classID: classID,
619 instanceID: meInstance,
620 }] = alarmBitmap
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530621 // Loop over the supported alarm list for this me
622 for alarmNo := range meAlarmMap {
623 // Check if alarmNo was previously active in the alarms, if yes clear it and remove it from active alarms
624 _, exists := am.activeAlarms[alarmInfo{
625 classID: classID,
626 instanceID: meInstance,
627 alarmNo: alarmNo,
628 }]
629 if exists {
630 // Clear this alarm if It is cleared now, in that case IsAlarmClear would return true
631 cleared, err := msg.IsAlarmClear(alarmNo)
632 if err != nil {
633 logger.Warnw(ctx, "unable-to-find-out-alarm-is-cleared", log.Fields{"class-id": classID,
634 "instance-id": meInstance, "alarm-no": alarmNo})
635 return err
636 }
637 if cleared {
638 // Clear this alarm.
639 am.clearAlarm(ctx, classID, meInstance, alarmNo)
640 }
641 } else {
642 // If alarm entry was not present in the list of active alarms, we need to see if this alarm is now active
643 // or not, if yes then raise it.
644 raised, err := msg.IsAlarmActive(alarmNo)
645 if err != nil {
646 logger.Warnw(ctx, "unable-to-find-out-alarm-is-raised", log.Fields{"class-id": classID,
647 "instance-id": meInstance, "alarm-no": alarmNo})
648 return err
649 }
650 if raised {
651 am.raiseAlarm(ctx, classID, meInstance, alarmNo)
652 }
653 }
654 }
655 return nil
656}
657
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000658func (am *OnuAlarmManager) raiseAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530659 am.activeAlarms[alarmInfo{
660 classID: classID,
661 instanceID: instanceID,
662 alarmNo: alarm,
663 }] = struct{}{}
Himani Chawlad3dac422021-03-13 02:31:31 +0530664
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530665 go am.sendAlarm(ctx, classID, instanceID, alarm, true)
666}
667
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000668func (am *OnuAlarmManager) clearAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530669 go am.sendAlarm(ctx, classID, instanceID, alarm, false)
670 delete(am.activeAlarms, alarmInfo{
671 classID: classID,
672 instanceID: instanceID,
673 alarmNo: alarm,
674 })
Himani Chawlad3dac422021-03-13 02:31:31 +0530675 key := meAlarmKey{
676 classID: classID,
677 instanceID: instanceID,
678 }
679 if am.alarmBitMapDB[key] == [alarmBitMapSizeBytes]byte{0} {
680 delete(am.alarmBitMapDB, key)
681 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530682}
683
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000684func (am *OnuAlarmManager) getIntfIDAlarm(ctx context.Context, classID me.ClassID, instanceID uint16) *uint32 {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530685 var intfID *uint32
686 if classID == circuitPackClassID || classID == physicalPathTerminationPointEthernetUniClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000687 for _, uniPort := range *am.pDeviceHandler.GetUniEntityMap() {
688 if uniPort.EntityID == instanceID {
689 intfID = &uniPort.PortNo
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530690 return intfID
691 }
692 }
693 } else if classID == aniGClassID || classID == onuGClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000694 intfID = am.pDeviceHandler.GetPonPortNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530695 return intfID
696 } else {
697 logger.Warnw(ctx, "me-not-supported", log.Fields{"class-id": classID, "instance-id": instanceID})
698 }
699 return nil
700}
701
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000702func (am *OnuAlarmManager) sendAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8, raised bool) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530703 context := make(map[string]string)
704 intfID := am.getIntfIDAlarm(ctx, classID, instanceID)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 onuID := am.deviceID
706 serialNo := am.pOnuDeviceEntry.GetPersSerialNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530707 if intfID == nil {
708 logger.Warn(ctx, "intf-id-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
709 return
710 }
711 context["onu-intf-id"] = fmt.Sprintf("%d", *intfID)
712 context["onu-id"] = onuID
713 context["onu-serial-number"] = serialNo
714
ozgecanetsia2f05ed32021-05-31 17:13:48 +0300715 raisedTimestamp := time.Now().Unix()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530716 eventDetails, err := am.getDeviceEventData(ctx, classID, alarm)
717 if err != nil {
718 logger.Warn(ctx, "event-details-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
719 return
720 }
721 suffixDesc := "Raised"
722 if !raised {
723 suffixDesc = "Cleared"
724 }
725 deviceEvent := &voltha.DeviceEvent{
726 ResourceId: onuID,
727 DeviceEventName: fmt.Sprintf("%s_RAISE_EVENT", eventDetails.EventName),
728 Description: fmt.Sprintf("%s Event - %s - %s", eventDetails.EventDescription, eventDetails.EventName,
729 suffixDesc),
730 Context: context,
731 }
732 _ = am.eventProxy.SendDeviceEvent(ctx, deviceEvent, eventDetails.EventCategory, eventDetails.EventSubCategory,
733 raisedTimestamp)
734}
Himani Chawlad3dac422021-03-13 02:31:31 +0530735
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000736func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530737 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
738}
739
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000740func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530741 //alarm sequence number wraps from 255 to 1.
742 if am.lastAlarmSequence == 255 {
743 am.lastAlarmSequence = 1
744 } else {
745 am.lastAlarmSequence++
746 }
747}
748
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000749func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530750 am.lastAlarmSequence = 0
751}
752
753// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000754func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530755 // flush alarm sync channel
756 select {
757 case <-am.eventChannel:
758 logger.Debug(ctx, "flushed-alarm-sync-channel")
759 default:
760 }
761 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000762 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530763 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
764 default:
765 }
766}
767
768// getDeviceEventData returns the event data for a device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000769func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530770 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
771 return onuEventDetails, nil
772 }
773 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
774}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000775
776//ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000777func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000778 am.onuAlarmManagerLock.Lock()
779 am.alarmUploadSeqNo = 0
780 am.alarmUploadNoOfCmds = 0
781 am.onuAlarmManagerLock.Unlock()
782}
783
784//IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000786 am.onuAlarmManagerLock.Lock()
787 am.alarmUploadSeqNo++
788 am.onuAlarmManagerLock.Unlock()
789}
790
791//GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000792func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000793 am.onuAlarmManagerLock.RLock()
794 value := am.alarmUploadSeqNo
795 am.onuAlarmManagerLock.RUnlock()
796 return value
797}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000798
799//GetAlarmMgrEventChannel gets alarm manager event channel
800func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
801 return am.eventChannel
802}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000803
804// PrepareForGarbageCollection - remove references to prepare for garbage collection
805func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
806 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
807 am.pDeviceHandler = nil
808 am.pOnuDeviceEntry = nil
809}