blob: ae872fa402916fb3884259706bd5cf17e87b4cc1 [file] [log] [blame]
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2021-2023 Open Networking Foundation (ONF) and the ONF Contributors
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
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
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000114 alarmUploadNoOfCmdsOrMEs uint16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000115 StopAlarmAuditTimer chan struct{}
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000116 isExtendedOmci bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117}
118
119// NewAlarmManager - TODO: add comment
120func NewAlarmManager(ctx context.Context, dh cmn.IdeviceHandler, onuDev cmn.IonuDeviceEntry) *OnuAlarmManager {
121 var alarmManager OnuAlarmManager
122 alarmManager.deviceID = dh.GetDeviceID()
123 logger.Debugw(ctx, "init-alarm-manager", log.Fields{"device-id": alarmManager.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530124 alarmManager.pDeviceHandler = dh
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125 alarmManager.pOnuDeviceEntry = onuDev
126 alarmManager.eventProxy = dh.GetEventProxy() // Or event proxy should be on cluster address ??
127 alarmManager.eventChannel = make(chan cmn.Message)
128 alarmManager.StopProcessingOmciMessages = make(chan bool)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530129 alarmManager.processMessage = false
130 alarmManager.activeAlarms = make(map[alarmInfo]struct{})
Himani Chawlad3dac422021-03-13 02:31:31 +0530131 alarmManager.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000132 alarmManager.StopAlarmAuditTimer = make(chan struct{})
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530133 alarmManager.onuEventsList = map[onuDevice]onuDeviceEvent{
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530134 {classID: circuitPackClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
135 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
136 {classID: circuitPackClassID, alarmno: 2}: {EventName: "ONU_SELF_TEST_FAIL",
137 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
138 {classID: circuitPackClassID, alarmno: 3}: {EventName: "ONU_LASER_EOL",
139 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser EOL"},
140 {classID: circuitPackClassID, alarmno: 4}: {EventName: "ONU_TEMP_YELLOW",
141 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
142 {classID: circuitPackClassID, alarmno: 5}: {EventName: "ONU_TEMP_RED",
143 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
144 {classID: physicalPathTerminationPointEthernetUniClassID, alarmno: 0}: {EventName: "ONU_Ethernet_UNI", EventCategory: voltha.EventCategory_EQUIPMENT,
145 EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "LAN Loss Of Signal"},
146 {classID: onuGClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
147 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
148 {classID: onuGClassID, alarmno: 6}: {EventName: "ONU_SELF_TEST_FAIL",
149 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
150 {classID: onuGClassID, alarmno: 7}: {EventName: "ONU_DYING_GASP",
151 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu DYING_GASP"},
152 {classID: onuGClassID, alarmno: 8}: {EventName: "ONU_TEMP_YELLOW",
153 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
154 {classID: onuGClassID, alarmno: 9}: {EventName: "ONU_TEMP_RED",
155 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
156 {classID: onuGClassID, alarmno: 10}: {EventName: "ONU_VOLTAGE_YELLOW",
157 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage yellow"},
158 {classID: onuGClassID, alarmno: 11}: {EventName: "ONU_VOLTAGE_RED",
159 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage red"},
160 {classID: aniGClassID, alarmno: 0}: {EventName: "ONU_LOW_RX_OPTICAL",
161 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low rx optical power"},
162 {classID: aniGClassID, alarmno: 1}: {EventName: "ONU_HIGH_RX_OPTICAL",
163 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high rx optical power"},
164 {classID: aniGClassID, alarmno: 4}: {EventName: "ONU_LOW_TX_OPTICAL",
165 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low tx optical power"},
166 {classID: aniGClassID, alarmno: 5}: {EventName: "ONU_HIGH_TX_OPTICAL",
167 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high tx optical power"},
168 {classID: aniGClassID, alarmno: 6}: {EventName: "ONU_LASER_BIAS_CURRENT",
169 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser bias current"},
170 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000171 alarmManager.AlarmSyncFsm = cmn.NewAdapterFsm("AlarmSync", alarmManager.deviceID, alarmManager.eventChannel)
172 alarmManager.AlarmSyncFsm.PFsm = fsm.NewFSM(
Himani Chawlad3dac422021-03-13 02:31:31 +0530173 asStDisabled,
174 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000175 {Name: AsEvStart, Src: []string{asStDisabled}, Dst: asStStarting},
176 {Name: AsEvAudit, Src: []string{asStStarting, asStInSync}, Dst: asStAuditing},
177 {Name: AsEvSync, Src: []string{asStStarting}, Dst: asStInSync},
178 {Name: AsEvSuccess, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStInSync},
179 {Name: AsEvFailure, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStAuditing},
180 {Name: AsEvResync, Src: []string{asStAuditing}, Dst: asStResynchronizing},
181 {Name: AsEvStop, Src: []string{asStDisabled, asStStarting, asStAuditing, asStInSync, asStIdle, asStResynchronizing}, Dst: asStDisabled},
Himani Chawlad3dac422021-03-13 02:31:31 +0530182 },
183 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000184 "enter_state": func(e *fsm.Event) { alarmManager.AlarmSyncFsm.LogFsmStateChange(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530185 "enter_" + asStStarting: func(e *fsm.Event) { alarmManager.asFsmStarting(ctx, e) },
186 "enter_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmAuditing(ctx, e) },
187 "enter_" + asStInSync: func(e *fsm.Event) { alarmManager.asFsmInSync(ctx, e) },
188 "enter_" + asStResynchronizing: func(e *fsm.Event) { alarmManager.asFsmResynchronizing(ctx, e) },
189 },
190 )
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530191 return &alarmManager
192}
193
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000194func (am *OnuAlarmManager) asFsmStarting(ctx context.Context, e *fsm.Event) {
195 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 +0530196 go am.processAlarmSyncMessages(ctx)
197 // Start the first audit, if audit interval configured, else reach the sync state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000198 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530199 select {
200 //Transition into auditing state, using a very shorter timeout delay here, hence it is the first audit
201 case <-time.After(defaultTimeoutDelay * time.Second):
202 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000203 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
204 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 +0530205 }
206 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000207 case <-am.StopAlarmAuditTimer:
208 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530209 return
210 }
211 } else {
212 // Transition into sync state directly.
213 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000214 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSync); err != nil {
215 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 +0530216 }
217 }()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530218 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530219}
220
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000221func (am *OnuAlarmManager) asFsmAuditing(ctx context.Context, e *fsm.Event) {
222 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 +0530223 // Always reset the buffered notifications and db copies before starting the audit
224 am.onuAlarmManagerLock.Lock()
225 am.bufferedNotifications = make([]*omci.AlarmNotificationMsg, 0)
226 am.oltDbCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
227 am.onuDBCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
228 am.onuAlarmManagerLock.Unlock()
229 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000230 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
231 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 +0530232 }
233 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000234 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarm(log.WithSpanFromContext(context.TODO(), ctx), 0,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000235 am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530236 // Transition to failure so that alarm sync can be restarted again
237 go failureTransition()
238 }
239}
240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000241func (am *OnuAlarmManager) asFsmResynchronizing(ctx context.Context, e *fsm.Event) {
242 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530243 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000244 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
245 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 +0530246 }
247 }
248 // See if there is any onu only diff, meaning the class and entity is only in onu DB
249 for alarm := range am.onuDBCopy {
250 if _, exists := am.oltDbCopy[meAlarmKey{
251 classID: alarm.classID,
252 instanceID: alarm.instanceID,
253 }]; !exists {
254 // We need to raise all such alarms as OLT wont have received notification for these alarms
255 omciAlarmMessage := &omci.AlarmNotificationMsg{
256 MeBasePacket: omci.MeBasePacket{
257 EntityClass: alarm.classID,
258 EntityInstance: alarm.instanceID,
259 },
260 AlarmBitmap: am.onuDBCopy[alarm],
261 }
262 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000263 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530264 // Transition to failure.
265 go failureTransition()
266 return
267 }
268 }
269 }
270 // See if there is any olt only diff, meaning the class and entity is only in olt DB
271 for alarm := range am.oltDbCopy {
272 if _, exists := am.onuDBCopy[meAlarmKey{
273 classID: alarm.classID,
274 instanceID: alarm.instanceID,
275 }]; !exists {
276 // We need to clear all such alarms as OLT might have stale data and the alarms are already cleared.
277 omciAlarmMessage := &omci.AlarmNotificationMsg{
278 MeBasePacket: omci.MeBasePacket{
279 EntityClass: alarm.classID,
280 EntityInstance: alarm.instanceID,
281 },
282 AlarmBitmap: am.oltDbCopy[alarm],
283 }
284 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000285 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530286 // Transition to failure
287 go failureTransition()
288 return
289 }
290 }
291 }
292 // See if there is any attribute difference
293 for alarm := range am.onuDBCopy {
294 if _, exists := am.oltDbCopy[alarm]; exists {
295 if am.onuDBCopy[alarm] != am.oltDbCopy[alarm] {
296 omciAlarmMessage := &omci.AlarmNotificationMsg{
297 MeBasePacket: omci.MeBasePacket{
298 EntityClass: alarm.classID,
299 EntityInstance: alarm.instanceID,
300 },
301 AlarmBitmap: am.onuDBCopy[alarm],
302 }
303 // We will assume that onudb is correct always in this case and process the changed bitmap.
304 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000305 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530306 // Transition to failure
307 go failureTransition()
308 return
309 }
310 }
311 }
312 }
313 // Send the buffered notifications if no failure.
314 for _, notif := range am.bufferedNotifications {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000315 logger.Debugw(ctx, "processing-buffered-alarm-notification", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530316 "notification": notif})
317 if err := am.processAlarmData(ctx, notif); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000318 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530319 go failureTransition()
320 }
321 }
322 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000323 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
324 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 +0530325 }
326 }()
327}
328
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000329func (am *OnuAlarmManager) asFsmInSync(ctx context.Context, e *fsm.Event) {
330 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
331 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530332 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000333 case <-time.After(am.pDeviceHandler.GetAlarmAuditInterval()):
Himani Chawlad3dac422021-03-13 02:31:31 +0530334 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
336 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 +0530337 }
338 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000339 case <-am.StopAlarmAuditTimer:
340 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530341 return
342 }
343 }
344}
345
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000346func (am *OnuAlarmManager) processAlarmSyncMessages(ctx context.Context) {
347 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 +0530348 for {
Himani Chawla1472c682021-03-17 17:11:14 +0530349 select {
350 case message, ok := <-am.eventChannel:
351 if !ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 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 +0530353 continue
354 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000355 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530356
Himani Chawla1472c682021-03-17 17:11:14 +0530357 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000358 case cmn.OMCI:
359 msg, _ := message.Data.(cmn.OmciMessage)
Himani Chawla1472c682021-03-17 17:11:14 +0530360 am.handleOmciMessage(ctx, msg)
361 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000362 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 +0530363 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 case <-am.StopProcessingOmciMessages:
365 logger.Infow(ctx, "alarm-manager-stop-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawla1472c682021-03-17 17:11:14 +0530366 am.onuAlarmManagerLock.Lock()
367 am.processMessage = false
368 am.activeAlarms = nil
369 am.alarmBitMapDB = nil
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000370 am.alarmUploadNoOfCmdsOrMEs = 0
Himani Chawla1472c682021-03-17 17:11:14 +0530371 am.alarmUploadSeqNo = 0
372 am.onuAlarmManagerLock.Unlock()
373 return
374
Himani Chawlad3dac422021-03-13 02:31:31 +0530375 }
376 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530377}
378
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379func (am *OnuAlarmManager) handleOmciMessage(ctx context.Context, msg cmn.OmciMessage) {
380 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530381 "msg-type": msg.OmciMsg.MessageType, "msg": msg})
382 switch msg.OmciMsg.MessageType {
383 case omci.GetAllAlarmsResponseType:
384 am.handleOmciGetAllAlarmsResponseMessage(ctx, msg)
385 case omci.GetAllAlarmsNextResponseType:
386 am.handleOmciGetAllAlarmNextResponseMessage(ctx, msg)
387 default:
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000388 logger.Warnw(ctx, "unknown-message-type", log.Fields{"device-id": am.deviceID, "msg-type": msg.OmciMsg.MessageType})
Himani Chawlad3dac422021-03-13 02:31:31 +0530389
390 }
391}
392
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000393func (am *OnuAlarmManager) handleOmciGetAllAlarmsResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530394 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsResponse)
395 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000396 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530397 return
398 }
399 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsResponse)
400 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000401 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530402 return
403 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 logger.Debugw(ctx, "get-all-alarm-response-data", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
405 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
406 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 +0530407 return
408 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000409 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000410 am.alarmUploadNoOfCmdsOrMEs = msgObj.NumberOfCommands
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000411 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530412 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000413 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
414 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 +0530415 }
416 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000417 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000418 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Himani Chawlad3dac422021-03-13 02:31:31 +0530419 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530420 am.resetAlarmSequence()
421 // Get a copy of the alarm bit map db.
422 for alarms, bitmap := range am.alarmBitMapDB {
423 am.oltDbCopy[alarms] = bitmap
424 }
425 am.onuAlarmManagerLock.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000426 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000427 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530428 // Transition to failure
429 go failureTransition()
430 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000431 } else if am.alarmUploadNoOfCmdsOrMEs == 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530432 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530433 am.resetAlarmSequence()
434 // Get a copy of the alarm bit map db.
435 for alarms, bitmap := range am.alarmBitMapDB {
436 am.oltDbCopy[alarms] = bitmap
437 }
438 am.onuAlarmManagerLock.Unlock()
439 if am.isAlarmDBDiffPresent(ctx) {
440 // transition to resync state
441 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000442 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
443 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 +0530444 }
445 }()
446 } else {
447 // Transition to sync state
448 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
450 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 +0530451 }
452 }()
453 }
454 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455 logger.Errorw(ctx, "invalid-number-of-commands-received", log.Fields{"device-id": am.deviceID,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000456 "upload-no-of-cmds": am.alarmUploadNoOfCmdsOrMEs, "upload-seq-no": am.alarmUploadSeqNo})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000457 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530458 go failureTransition()
459 }
460}
461
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462func (am *OnuAlarmManager) handleOmciGetAllAlarmNextResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530463 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsNextResponse)
464
465 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000466 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530467 return
468 }
469 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsNextResponse)
470 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000471 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530472 return
473 }
474 logger.Debugw(ctx, "get-all-alarms-next-response-data",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000475 log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawlad3dac422021-03-13 02:31:31 +0530476 meClassID := msgObj.AlarmEntityClass
477 meEntityID := msgObj.AlarmEntityInstance
478 meAlarmBitMap := msgObj.AlarmBitMap
479
480 am.onuAlarmManagerLock.Lock()
481 am.onuDBCopy[meAlarmKey{
482 classID: meClassID,
483 instanceID: meEntityID,
484 }] = meAlarmBitMap
485 am.onuAlarmManagerLock.Unlock()
486 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
488 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 +0530489 }
490 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000491 if msg.OmciMsg.DeviceIdentifier == omci.ExtendedIdent {
492 logger.Debugw(ctx, "get-all-alarms-next-response-additional-data",
493 log.Fields{"device-id": am.deviceID, "additional-data": msgObj.AdditionalAlarms})
494
495 for _, additionalAlarmReport := range msgObj.AdditionalAlarms {
496 meClassID := additionalAlarmReport.AlarmEntityClass
497 meEntityID := additionalAlarmReport.AlarmEntityInstance
498 meAlarmBitMap := additionalAlarmReport.AlarmBitMap
499
500 am.onuAlarmManagerLock.Lock()
501 am.onuDBCopy[meAlarmKey{
502 classID: meClassID,
503 instanceID: meEntityID,
504 }] = meAlarmBitMap
505 am.onuAlarmManagerLock.Unlock()
506
507 am.IncrementAlarmUploadSeqNo()
508 }
509 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000510 am.onuAlarmManagerLock.RLock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000511 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000512 am.onuAlarmManagerLock.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000514 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530515 // Transition to failure
516 go failureTransition()
517 } //TODO: needs to handle timeouts
518 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000519 am.onuAlarmManagerLock.RUnlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530520 if am.isAlarmDBDiffPresent(ctx) {
521 // transition to resync state
522 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
524 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 +0530525 }
526 }()
527 } else {
528 // Transition to sync state
529 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000530 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
531 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 +0530532 }
533 }()
534 }
535 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530536}
537
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000538// StartOMCIAlarmMessageProcessing - TODO: add comment: add comment
539func (am *OnuAlarmManager) StartOMCIAlarmMessageProcessing(ctx context.Context) {
540 logger.Infow(ctx, "alarm-manager-start-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530541 am.onuAlarmManagerLock.Lock()
542 am.processMessage = true
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530543 if am.activeAlarms == nil {
544 am.activeAlarms = make(map[alarmInfo]struct{})
545 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530546 am.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000547 // when instantiating alarm manager it was too early, but now we can check for ONU's extended OMCI support
548 am.isExtendedOmci = am.pOnuDeviceEntry.GetPersIsExtOmciSupported()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530549 am.onuAlarmManagerLock.Unlock()
Himani Chawla1472c682021-03-17 17:11:14 +0530550 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
551
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
553 if err := am.AlarmSyncFsm.PFsm.Event(AsEvStart); err != nil {
554 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 +0530555 return
556 }
557 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 logger.Errorw(ctx, "wrong-state-of-alarm-sync-fsm-want-disabled", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current()),
559 "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530560 return
561 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 logger.Debugw(ctx, "alarm-sync-fsm-started", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current())})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530563}
564
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565// HandleOmciAlarmNotificationMessage - TODO: add comment
566func (am *OnuAlarmManager) HandleOmciAlarmNotificationMessage(ctx context.Context, msg cmn.OmciMessage) {
567 logger.Debugw(ctx, "omci-alarm-notification-msg", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530568 "msg-type": msg.OmciMsg.MessageType})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530569
Himani Chawla7998aa92021-04-07 14:16:52 +0530570 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeAlarmNotification)
571 if msgLayer == nil {
572 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530574 return
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530575 }
Himani Chawla7998aa92021-04-07 14:16:52 +0530576 msgObj, msgOk := msgLayer.(*omci.AlarmNotificationMsg)
577 if !msgOk {
578 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530580 return
581 }
582 //Alarm Notification decoding at omci lib validates that the me class ID supports the
583 // alarm notifications.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 logger.Debugw(ctx, "alarm-notification-data-received", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawla7998aa92021-04-07 14:16:52 +0530585 if err := am.processAlarmData(ctx, msgObj); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530587 }
588
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530589}
590
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591func (am *OnuAlarmManager) processAlarmData(ctx context.Context, msg *omci.AlarmNotificationMsg) error {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530592 classID := msg.EntityClass
593 sequenceNo := msg.AlarmSequenceNumber
594 meInstance := msg.EntityInstance
595 alarmBitmap := msg.AlarmBitmap
596 logger.Debugw(ctx, "processing-alarm-data", log.Fields{"class-id": classID, "instance-id": meInstance,
597 "alarmBitMap": alarmBitmap, "sequence-no": sequenceNo})
Himani Chawla7998aa92021-04-07 14:16:52 +0530598 am.onuAlarmManagerLock.Lock()
599 defer am.onuAlarmManagerLock.Unlock()
600 if !am.processMessage {
601 logger.Warnw(ctx, "ignoring-alarm-notification-received-for-me-as-channel-for-processing-is-closed",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530603 return fmt.Errorf("alarm-manager-is-in-stopped-state")
604 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 if _, present := am.pOnuDeviceEntry.GetOnuDB().MeDb[classID][meInstance]; !present {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000606 logger.Errorw(ctx, "me-class-instance-not-present",
607 log.Fields{"class-id": classID, "instance-id": meInstance, "device-id": am.deviceID})
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530608 return fmt.Errorf("me-class-%d-instance-%d-not-present", classID, meInstance)
609 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530610 if sequenceNo > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 if am.AlarmSyncFsm.PFsm.Is(asStAuditing) || am.AlarmSyncFsm.PFsm.Is(asStResynchronizing) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530612 am.bufferedNotifications = append(am.bufferedNotifications, msg)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000613 logger.Debugw(ctx, "adding-notification-to-buffered-notification-list", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530614 "notification": msg})
615 return nil
Andrea Campanellace915292021-03-12 17:59:35 +0000616 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530617 am.incrementAlarmSequence()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 if sequenceNo != am.lastAlarmSequence && am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530619 // signal early audit, if no match(if we are reaching here it means that audit is not going on currently)
620 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000621 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
622 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 +0530623 }
624 }()
625 }
626 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530627 entity, omciErr := me.LoadManagedEntityDefinition(classID,
628 me.ParamData{EntityID: meInstance})
629 if omciErr.StatusCode() != me.Success {
630 //log error and return
631 logger.Error(ctx, "unable-to-get-managed-entity", log.Fields{"class-id": classID, "instance-id": meInstance})
632 return fmt.Errorf("unable-to-get-managed-entity-class-%d-instance-%d", classID, meInstance)
633 }
634 meAlarmMap := entity.GetAlarmMap()
635 if meAlarmMap == nil {
636 logger.Error(ctx, "unable-to-get-managed-entity-alarm-map", log.Fields{"class-id": classID, "instance-id": meInstance})
637 return fmt.Errorf("unable-to-get-managed-entity-alarm-map-%d-instance-%d", classID, meInstance)
638 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530639
640 am.alarmBitMapDB[meAlarmKey{
641 classID: classID,
642 instanceID: meInstance,
643 }] = alarmBitmap
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530644 // Loop over the supported alarm list for this me
645 for alarmNo := range meAlarmMap {
646 // Check if alarmNo was previously active in the alarms, if yes clear it and remove it from active alarms
647 _, exists := am.activeAlarms[alarmInfo{
648 classID: classID,
649 instanceID: meInstance,
650 alarmNo: alarmNo,
651 }]
652 if exists {
653 // Clear this alarm if It is cleared now, in that case IsAlarmClear would return true
654 cleared, err := msg.IsAlarmClear(alarmNo)
655 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000656 logger.Warnw(ctx, "unable-to-find-out-alarm-is-cleared", log.Fields{"device-id": am.deviceID,
657 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530658 return err
659 }
660 if cleared {
661 // Clear this alarm.
662 am.clearAlarm(ctx, classID, meInstance, alarmNo)
663 }
664 } else {
665 // If alarm entry was not present in the list of active alarms, we need to see if this alarm is now active
666 // or not, if yes then raise it.
667 raised, err := msg.IsAlarmActive(alarmNo)
668 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000669 logger.Warnw(ctx, "unable-to-find-out-alarm-is-raised", log.Fields{"device-id": am.deviceID,
670 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530671 return err
672 }
673 if raised {
674 am.raiseAlarm(ctx, classID, meInstance, alarmNo)
675 }
676 }
677 }
678 return nil
679}
680
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000681func (am *OnuAlarmManager) raiseAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530682 am.activeAlarms[alarmInfo{
683 classID: classID,
684 instanceID: instanceID,
685 alarmNo: alarm,
686 }] = struct{}{}
Himani Chawlad3dac422021-03-13 02:31:31 +0530687
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530688 go am.sendAlarm(ctx, classID, instanceID, alarm, true)
689}
690
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000691func (am *OnuAlarmManager) clearAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530692 go am.sendAlarm(ctx, classID, instanceID, alarm, false)
693 delete(am.activeAlarms, alarmInfo{
694 classID: classID,
695 instanceID: instanceID,
696 alarmNo: alarm,
697 })
Himani Chawlad3dac422021-03-13 02:31:31 +0530698 key := meAlarmKey{
699 classID: classID,
700 instanceID: instanceID,
701 }
702 if am.alarmBitMapDB[key] == [alarmBitMapSizeBytes]byte{0} {
703 delete(am.alarmBitMapDB, key)
704 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530705}
706
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000707func (am *OnuAlarmManager) getIntfIDAlarm(ctx context.Context, classID me.ClassID, instanceID uint16) *uint32 {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530708 var intfID *uint32
709 if classID == circuitPackClassID || classID == physicalPathTerminationPointEthernetUniClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000710 for _, uniPort := range *am.pDeviceHandler.GetUniEntityMap() {
711 if uniPort.EntityID == instanceID {
712 intfID = &uniPort.PortNo
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530713 return intfID
714 }
715 }
716 } else if classID == aniGClassID || classID == onuGClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000717 intfID = am.pDeviceHandler.GetPonPortNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530718 return intfID
719 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000720 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 +0530721 }
722 return nil
723}
724
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725func (am *OnuAlarmManager) sendAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8, raised bool) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530726 context := make(map[string]string)
727 intfID := am.getIntfIDAlarm(ctx, classID, instanceID)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000728 onuID := am.deviceID
729 serialNo := am.pOnuDeviceEntry.GetPersSerialNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530730 if intfID == nil {
731 logger.Warn(ctx, "intf-id-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
732 return
733 }
734 context["onu-intf-id"] = fmt.Sprintf("%d", *intfID)
735 context["onu-id"] = onuID
736 context["onu-serial-number"] = serialNo
737
ozgecanetsia2f05ed32021-05-31 17:13:48 +0300738 raisedTimestamp := time.Now().Unix()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530739 eventDetails, err := am.getDeviceEventData(ctx, classID, alarm)
740 if err != nil {
741 logger.Warn(ctx, "event-details-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
742 return
743 }
744 suffixDesc := "Raised"
745 if !raised {
746 suffixDesc = "Cleared"
747 }
748 deviceEvent := &voltha.DeviceEvent{
749 ResourceId: onuID,
750 DeviceEventName: fmt.Sprintf("%s_RAISE_EVENT", eventDetails.EventName),
751 Description: fmt.Sprintf("%s Event - %s - %s", eventDetails.EventDescription, eventDetails.EventName,
752 suffixDesc),
753 Context: context,
754 }
755 _ = am.eventProxy.SendDeviceEvent(ctx, deviceEvent, eventDetails.EventCategory, eventDetails.EventSubCategory,
756 raisedTimestamp)
757}
Himani Chawlad3dac422021-03-13 02:31:31 +0530758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530760 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
761}
762
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530764 //alarm sequence number wraps from 255 to 1.
765 if am.lastAlarmSequence == 255 {
766 am.lastAlarmSequence = 1
767 } else {
768 am.lastAlarmSequence++
769 }
770}
771
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000772func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530773 am.lastAlarmSequence = 0
774}
775
776// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000777func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530778 // flush alarm sync channel
779 select {
780 case <-am.eventChannel:
781 logger.Debug(ctx, "flushed-alarm-sync-channel")
782 default:
783 }
784 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530786 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
787 default:
788 }
789}
790
791// getDeviceEventData returns the event data for a device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000792func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530793 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
794 return onuEventDetails, nil
795 }
796 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
797}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000798
799//ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000801 am.onuAlarmManagerLock.Lock()
802 am.alarmUploadSeqNo = 0
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000803 am.alarmUploadNoOfCmdsOrMEs = 0
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000804 am.onuAlarmManagerLock.Unlock()
805}
806
807//IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000808func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000809 am.onuAlarmManagerLock.Lock()
810 am.alarmUploadSeqNo++
811 am.onuAlarmManagerLock.Unlock()
812}
813
814//GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000816 am.onuAlarmManagerLock.RLock()
817 value := am.alarmUploadSeqNo
818 am.onuAlarmManagerLock.RUnlock()
819 return value
820}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821
822//GetAlarmMgrEventChannel gets alarm manager event channel
823func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
824 return am.eventChannel
825}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000826
827// PrepareForGarbageCollection - remove references to prepare for garbage collection
828func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
829 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
830 am.pDeviceHandler = nil
831 am.pOnuDeviceEntry = nil
832}