blob: cb9019b5868c644d414f5c12d86e509c4281e5a1 [file] [log] [blame]
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2021-2023 Open Networking Foundation (ONF) and the ONF Contributors
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package almgr provides the utilities for managing alarm notifications
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package almgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053019
20import (
21 "context"
22 "errors"
23 "fmt"
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +000024 "reflect"
25 "sync"
26 "time"
27
Himani Chawlad3dac422021-03-13 02:31:31 +053028 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000029 "github.com/opencord/omci-lib-go/v2"
30 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040031 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
32 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000033 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
praneeth nalmas5a0a5502022-12-23 15:57:00 +053034 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo7d3c5582021-08-11 18:09:44 -040035 "github.com/opencord/voltha-protos/v5/go/voltha"
praneeth kumar nalmas3947c582023-12-13 15:38:50 +053036 "google.golang.org/grpc/codes"
37 "google.golang.org/grpc/status"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053038)
39
40const (
41 circuitPackClassID = me.CircuitPackClassID
42 physicalPathTerminationPointEthernetUniClassID = me.PhysicalPathTerminationPointEthernetUniClassID
43 onuGClassID = me.OnuGClassID
44 aniGClassID = me.AniGClassID
Himani Chawlad3dac422021-03-13 02:31:31 +053045 defaultTimeoutDelay = 10
46 alarmBitMapSizeBytes = 28
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053047)
48
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000049// events of alarm sync FSM
Himani Chawlad3dac422021-03-13 02:31:31 +053050const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000051 AsEvStart = "AsEvStart"
52 AsEvStop = "AsEvStop"
53 AsEvAudit = "AsEvAudit"
54 AsEvSync = "AsEvSync"
55 AsEvSuccess = "AsEvSuccess"
56 AsEvFailure = "AsEvFailure"
57 AsEvResync = "AsEvResync"
Himani Chawlad3dac422021-03-13 02:31:31 +053058)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000059
60// states of alarm sync FSM
Himani Chawlad3dac422021-03-13 02:31:31 +053061const (
Himani Chawlad3dac422021-03-13 02:31:31 +053062 asStStarting = "asStStarting"
63 asStDisabled = "asStDisabled"
64 asStInSync = "asStInSync"
65 asStAuditing = "asStAuditing"
66 asStResynchronizing = "asStResynchronizing"
67 asStIdle = "asStIdle"
68)
69
70//const cAsFsmIdleState = asStIdle not using idle state currently
71
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053072type alarmInfo struct {
73 classID me.ClassID
74 instanceID uint16
75 alarmNo uint8
76}
77
78type alarms map[alarmInfo]struct{}
79
Himani Chawlad3dac422021-03-13 02:31:31 +053080type meAlarmKey struct {
81 classID me.ClassID
82 instanceID uint16
83}
84
85type alarmBitMapDB map[meAlarmKey][alarmBitMapSizeBytes]byte
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053086
87type onuDevice struct {
88 classID me.ClassID
89 alarmno uint8
90}
91type onuDeviceEvent struct {
92 EventName string
93 EventCategory eventif.EventCategory
94 EventSubCategory eventif.EventSubCategory
95 EventDescription string
96}
97
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000098// OnuAlarmManager holds alarm manager related data
99type OnuAlarmManager struct {
100 deviceID string
101 pDeviceHandler cmn.IdeviceHandler
102 pOnuDeviceEntry cmn.IonuDeviceEntry
103 eventProxy eventif.EventProxy
104 StopProcessingOmciMessages chan bool
105 eventChannel chan cmn.Message
106 onuAlarmManagerLock sync.RWMutex
107 processMessage bool
108 activeAlarms alarms
109 alarmBitMapDB alarmBitMapDB
110 onuEventsList map[onuDevice]onuDeviceEvent
111 lastAlarmSequence uint8
112 AlarmSyncFsm *cmn.AdapterFsm
113 oltDbCopy alarmBitMapDB
114 onuDBCopy alarmBitMapDB
115 bufferedNotifications []*omci.AlarmNotificationMsg
116 alarmUploadSeqNo uint16
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000117 alarmUploadNoOfCmdsOrMEs uint16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 StopAlarmAuditTimer chan struct{}
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000119 isExtendedOmci bool
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530120 AsyncAlarmsCommChan chan struct{}
121 isAsyncAlarmRequest bool
122 onuAlarmRequestLock sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000123}
124
125// NewAlarmManager - TODO: add comment
126func NewAlarmManager(ctx context.Context, dh cmn.IdeviceHandler, onuDev cmn.IonuDeviceEntry) *OnuAlarmManager {
127 var alarmManager OnuAlarmManager
128 alarmManager.deviceID = dh.GetDeviceID()
129 logger.Debugw(ctx, "init-alarm-manager", log.Fields{"device-id": alarmManager.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530130 alarmManager.pDeviceHandler = dh
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000131 alarmManager.pOnuDeviceEntry = onuDev
132 alarmManager.eventProxy = dh.GetEventProxy() // Or event proxy should be on cluster address ??
133 alarmManager.eventChannel = make(chan cmn.Message)
134 alarmManager.StopProcessingOmciMessages = make(chan bool)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530135 alarmManager.processMessage = false
136 alarmManager.activeAlarms = make(map[alarmInfo]struct{})
Himani Chawlad3dac422021-03-13 02:31:31 +0530137 alarmManager.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000138 alarmManager.StopAlarmAuditTimer = make(chan struct{})
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530139 alarmManager.AsyncAlarmsCommChan = make(chan struct{})
140 alarmManager.isAsyncAlarmRequest = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530141 alarmManager.onuEventsList = map[onuDevice]onuDeviceEvent{
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530142 {classID: circuitPackClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
143 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
144 {classID: circuitPackClassID, alarmno: 2}: {EventName: "ONU_SELF_TEST_FAIL",
145 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
146 {classID: circuitPackClassID, alarmno: 3}: {EventName: "ONU_LASER_EOL",
147 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser EOL"},
148 {classID: circuitPackClassID, alarmno: 4}: {EventName: "ONU_TEMP_YELLOW",
149 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
150 {classID: circuitPackClassID, alarmno: 5}: {EventName: "ONU_TEMP_RED",
151 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
152 {classID: physicalPathTerminationPointEthernetUniClassID, alarmno: 0}: {EventName: "ONU_Ethernet_UNI", EventCategory: voltha.EventCategory_EQUIPMENT,
153 EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "LAN Loss Of Signal"},
154 {classID: onuGClassID, alarmno: 0}: {EventName: "ONU_EQUIPMENT",
155 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu equipment"},
156 {classID: onuGClassID, alarmno: 6}: {EventName: "ONU_SELF_TEST_FAIL",
157 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu self-test failure"},
158 {classID: onuGClassID, alarmno: 7}: {EventName: "ONU_DYING_GASP",
159 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu DYING_GASP"},
160 {classID: onuGClassID, alarmno: 8}: {EventName: "ONU_TEMP_YELLOW",
161 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature yellow"},
162 {classID: onuGClassID, alarmno: 9}: {EventName: "ONU_TEMP_RED",
163 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu temperature red"},
164 {classID: onuGClassID, alarmno: 10}: {EventName: "ONU_VOLTAGE_YELLOW",
165 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage yellow"},
166 {classID: onuGClassID, alarmno: 11}: {EventName: "ONU_VOLTAGE_RED",
167 EventCategory: voltha.EventCategory_ENVIRONMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu voltage red"},
168 {classID: aniGClassID, alarmno: 0}: {EventName: "ONU_LOW_RX_OPTICAL",
169 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low rx optical power"},
170 {classID: aniGClassID, alarmno: 1}: {EventName: "ONU_HIGH_RX_OPTICAL",
171 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high rx optical power"},
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300172 {classID: aniGClassID, alarmno: 2}: {EventName: "ONU_BIT_ERROR_BASED_SIGNAL_FAIL",
173 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu bit error based signal fail"},
174 {classID: aniGClassID, alarmno: 3}: {EventName: "ONU_BIT_ERROR_BASED_SIGNAL_DEGRADE",
175 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu bit error based signal degrade"},
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530176 {classID: aniGClassID, alarmno: 4}: {EventName: "ONU_LOW_TX_OPTICAL",
177 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu low tx optical power"},
178 {classID: aniGClassID, alarmno: 5}: {EventName: "ONU_HIGH_TX_OPTICAL",
179 EventCategory: voltha.EventCategory_COMMUNICATION, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu high tx optical power"},
180 {classID: aniGClassID, alarmno: 6}: {EventName: "ONU_LASER_BIAS_CURRENT",
181 EventCategory: voltha.EventCategory_EQUIPMENT, EventSubCategory: voltha.EventSubCategory_ONU, EventDescription: "onu laser bias current"},
182 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000183 alarmManager.AlarmSyncFsm = cmn.NewAdapterFsm("AlarmSync", alarmManager.deviceID, alarmManager.eventChannel)
184 alarmManager.AlarmSyncFsm.PFsm = fsm.NewFSM(
Himani Chawlad3dac422021-03-13 02:31:31 +0530185 asStDisabled,
186 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000187 {Name: AsEvStart, Src: []string{asStDisabled}, Dst: asStStarting},
188 {Name: AsEvAudit, Src: []string{asStStarting, asStInSync}, Dst: asStAuditing},
189 {Name: AsEvSync, Src: []string{asStStarting}, Dst: asStInSync},
190 {Name: AsEvSuccess, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStInSync},
191 {Name: AsEvFailure, Src: []string{asStAuditing, asStResynchronizing}, Dst: asStAuditing},
192 {Name: AsEvResync, Src: []string{asStAuditing}, Dst: asStResynchronizing},
193 {Name: AsEvStop, Src: []string{asStDisabled, asStStarting, asStAuditing, asStInSync, asStIdle, asStResynchronizing}, Dst: asStDisabled},
Himani Chawlad3dac422021-03-13 02:31:31 +0530194 },
195 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000196 "enter_state": func(e *fsm.Event) { alarmManager.AlarmSyncFsm.LogFsmStateChange(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530197 "enter_" + asStStarting: func(e *fsm.Event) { alarmManager.asFsmStarting(ctx, e) },
198 "enter_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmAuditing(ctx, e) },
199 "enter_" + asStInSync: func(e *fsm.Event) { alarmManager.asFsmInSync(ctx, e) },
200 "enter_" + asStResynchronizing: func(e *fsm.Event) { alarmManager.asFsmResynchronizing(ctx, e) },
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530201 "leave_" + asStAuditing: func(e *fsm.Event) { alarmManager.asFsmLeaveAuditing(ctx, e) },
Himani Chawlad3dac422021-03-13 02:31:31 +0530202 },
203 )
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530204 return &alarmManager
205}
206
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000207func (am *OnuAlarmManager) asFsmStarting(ctx context.Context, e *fsm.Event) {
208 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 +0530209 go am.processAlarmSyncMessages(ctx)
210 // Start the first audit, if audit interval configured, else reach the sync state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000211 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530212 select {
213 //Transition into auditing state, using a very shorter timeout delay here, hence it is the first audit
214 case <-time.After(defaultTimeoutDelay * time.Second):
215 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000216 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
217 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 +0530218 }
219 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000220 case <-am.StopAlarmAuditTimer:
221 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530222 return
223 }
224 } else {
225 // Transition into sync state directly.
226 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000227 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSync); err != nil {
228 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 +0530229 }
230 }()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530231 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530232}
233
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000234func (am *OnuAlarmManager) asFsmAuditing(ctx context.Context, e *fsm.Event) {
235 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 +0530236 // Always reset the buffered notifications and db copies before starting the audit
237 am.onuAlarmManagerLock.Lock()
238 am.bufferedNotifications = make([]*omci.AlarmNotificationMsg, 0)
239 am.oltDbCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
240 am.onuDBCopy = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
241 am.onuAlarmManagerLock.Unlock()
242 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 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000247 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarm(log.WithSpanFromContext(context.TODO(), ctx), 0,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000248 am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530249 // Transition to failure so that alarm sync can be restarted again
250 go failureTransition()
251 }
252}
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530253func (am *OnuAlarmManager) asFsmLeaveAuditing(ctx context.Context, e *fsm.Event) {
254 logger.Debugw(ctx, "alarm-sync-fsm-leave-auditing state", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530255}
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530256
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000257func (am *OnuAlarmManager) asFsmResynchronizing(ctx context.Context, e *fsm.Event) {
258 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530259 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000260 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
261 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 +0530262 }
263 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530264
265 // Process onu only differences
266 if err := am.processOnuOnlyDifferences(ctx, failureTransition); err != nil {
267 return
Himani Chawlad3dac422021-03-13 02:31:31 +0530268 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530269
270 // Process olt only differences
271 if err := am.processOltOnlyDifferences(ctx, failureTransition); err != nil {
272 return
Himani Chawlad3dac422021-03-13 02:31:31 +0530273 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530274
275 // Process attribute differences
276 if err := am.processAttributeDifferences(ctx, failureTransition); err != nil {
277 return
Himani Chawlad3dac422021-03-13 02:31:31 +0530278 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530279
280 // Process buffered notifications
281 if err := am.processBufferedNotifications(ctx, failureTransition); err != nil {
282 return
Himani Chawlad3dac422021-03-13 02:31:31 +0530283 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530284
Himani Chawlad3dac422021-03-13 02:31:31 +0530285 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000286 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
287 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 +0530288 }
289 }()
290}
291
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000292func (am *OnuAlarmManager) asFsmInSync(ctx context.Context, e *fsm.Event) {
293 logger.Debugw(ctx, "alarm-sync-fsm", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530294
295 if am.isAsyncAlarmRequest {
296 logger.Debugw(ctx, "alarm-sync-fsm-before entering the sync state process the updated ONU alarms ", log.Fields{"state": e.FSM.Current(), "device-id": am.deviceID})
297 am.AsyncAlarmsCommChan <- struct{}{}
298 am.isAsyncAlarmRequest = false
299
300 }
301
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000302 if am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530303 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000304 case <-time.After(am.pDeviceHandler.GetAlarmAuditInterval()):
Himani Chawlad3dac422021-03-13 02:31:31 +0530305 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000306 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
307 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 +0530308 }
309 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000310 case <-am.StopAlarmAuditTimer:
311 logger.Infow(ctx, "stopping-alarm-timer", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530312 return
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530313
314 case <-am.AsyncAlarmsCommChan:
315 go func() {
316 logger.Debugw(ctx, "On demand Auditing the ONU for Alarms ", log.Fields{"device-id": am.deviceID})
317 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
318 logger.Errorw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing, use current snapshot of alarms", log.Fields{"device-id": am.deviceID, "err": err})
319 am.isAsyncAlarmRequest = false
320 am.AsyncAlarmsCommChan <- struct{}{}
321 }
322 }()
323
Himani Chawlad3dac422021-03-13 02:31:31 +0530324 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530325 } else {
326 <-am.AsyncAlarmsCommChan
327 go func() {
328 logger.Debugw(ctx, "On demand Auditing the ONU for Alarms ", log.Fields{"device-id": am.deviceID})
329 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
330 logger.Errorw(ctx, "alarm-sync-fsm-cannot-go-to-state-auditing, use current snapshot of alarms", log.Fields{"device-id": am.deviceID, "err": err})
331 am.isAsyncAlarmRequest = false
332 am.AsyncAlarmsCommChan <- struct{}{}
333 }
334 }()
Himani Chawlad3dac422021-03-13 02:31:31 +0530335 }
336}
337
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338func (am *OnuAlarmManager) processAlarmSyncMessages(ctx context.Context) {
339 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 +0530340 for {
Himani Chawla1472c682021-03-17 17:11:14 +0530341 select {
342 case message, ok := <-am.eventChannel:
343 if !ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000344 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 +0530345 continue
346 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000347 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530348
Himani Chawla1472c682021-03-17 17:11:14 +0530349 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 case cmn.OMCI:
351 msg, _ := message.Data.(cmn.OmciMessage)
Himani Chawla1472c682021-03-17 17:11:14 +0530352 am.handleOmciMessage(ctx, msg)
353 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000354 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 +0530355 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 case <-am.StopProcessingOmciMessages:
357 logger.Infow(ctx, "alarm-manager-stop-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawla1472c682021-03-17 17:11:14 +0530358 am.onuAlarmManagerLock.Lock()
359 am.processMessage = false
360 am.activeAlarms = nil
361 am.alarmBitMapDB = nil
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000362 am.alarmUploadNoOfCmdsOrMEs = 0
Himani Chawla1472c682021-03-17 17:11:14 +0530363 am.alarmUploadSeqNo = 0
364 am.onuAlarmManagerLock.Unlock()
365 return
366
Himani Chawlad3dac422021-03-13 02:31:31 +0530367 }
368 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530369}
370
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371func (am *OnuAlarmManager) handleOmciMessage(ctx context.Context, msg cmn.OmciMessage) {
372 logger.Debugw(ctx, "alarm-sync-omci-message-received", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530373 "msg-type": msg.OmciMsg.MessageType, "msg": msg})
374 switch msg.OmciMsg.MessageType {
375 case omci.GetAllAlarmsResponseType:
376 am.handleOmciGetAllAlarmsResponseMessage(ctx, msg)
377 case omci.GetAllAlarmsNextResponseType:
378 am.handleOmciGetAllAlarmNextResponseMessage(ctx, msg)
379 default:
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000380 logger.Warnw(ctx, "unknown-message-type", log.Fields{"device-id": am.deviceID, "msg-type": msg.OmciMsg.MessageType})
Himani Chawlad3dac422021-03-13 02:31:31 +0530381
382 }
383}
384
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000385func (am *OnuAlarmManager) handleOmciGetAllAlarmsResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530386 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsResponse)
387 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530389 return
390 }
391 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsResponse)
392 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000393 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530394 return
395 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000396 logger.Debugw(ctx, "get-all-alarm-response-data", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
397 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
398 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 +0530399 return
400 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000401 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000402 am.alarmUploadNoOfCmdsOrMEs = msgObj.NumberOfCommands
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000403 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530404 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
406 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 +0530407 }
408 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000409 am.onuAlarmManagerLock.Lock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000410 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Himani Chawlad3dac422021-03-13 02:31:31 +0530411 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530412 am.resetAlarmSequence()
413 // Get a copy of the alarm bit map db.
414 for alarms, bitmap := range am.alarmBitMapDB {
415 am.oltDbCopy[alarms] = bitmap
416 }
417 am.onuAlarmManagerLock.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000418 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000419 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530420 // Transition to failure
421 go failureTransition()
422 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000423 } else if am.alarmUploadNoOfCmdsOrMEs == 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530424 // Reset Onu Alarm Sequence
Himani Chawlad3dac422021-03-13 02:31:31 +0530425 am.resetAlarmSequence()
426 // Get a copy of the alarm bit map db.
427 for alarms, bitmap := range am.alarmBitMapDB {
428 am.oltDbCopy[alarms] = bitmap
429 }
430 am.onuAlarmManagerLock.Unlock()
431 if am.isAlarmDBDiffPresent(ctx) {
432 // transition to resync state
433 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
435 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 +0530436 }
437 }()
438 } else {
439 // Transition to sync state
440 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
442 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 +0530443 }
444 }()
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530445
Himani Chawlad3dac422021-03-13 02:31:31 +0530446 }
447 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000448 logger.Errorw(ctx, "invalid-number-of-commands-received", log.Fields{"device-id": am.deviceID,
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000449 "upload-no-of-cmds": am.alarmUploadNoOfCmdsOrMEs, "upload-seq-no": am.alarmUploadSeqNo})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000450 am.onuAlarmManagerLock.Unlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530451 go failureTransition()
452 }
453}
454
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455func (am *OnuAlarmManager) handleOmciGetAllAlarmNextResponseMessage(ctx context.Context, msg cmn.OmciMessage) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530456 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeGetAllAlarmsNextResponse)
457
458 if msgLayer == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000459 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530460 return
461 }
462 msgObj, msgOk := msgLayer.(*omci.GetAllAlarmsNextResponse)
463 if !msgOk {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned", log.Fields{"device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530465 return
466 }
467 logger.Debugw(ctx, "get-all-alarms-next-response-data",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawlad3dac422021-03-13 02:31:31 +0530469 meClassID := msgObj.AlarmEntityClass
470 meEntityID := msgObj.AlarmEntityInstance
471 meAlarmBitMap := msgObj.AlarmBitMap
472
473 am.onuAlarmManagerLock.Lock()
474 am.onuDBCopy[meAlarmKey{
475 classID: meClassID,
476 instanceID: meEntityID,
477 }] = meAlarmBitMap
478 am.onuAlarmManagerLock.Unlock()
479 failureTransition := func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000480 if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
481 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 +0530482 }
483 }
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000484 if msg.OmciMsg.DeviceIdentifier == omci.ExtendedIdent {
485 logger.Debugw(ctx, "get-all-alarms-next-response-additional-data",
486 log.Fields{"device-id": am.deviceID, "additional-data": msgObj.AdditionalAlarms})
487
488 for _, additionalAlarmReport := range msgObj.AdditionalAlarms {
489 meClassID := additionalAlarmReport.AlarmEntityClass
490 meEntityID := additionalAlarmReport.AlarmEntityInstance
491 meAlarmBitMap := additionalAlarmReport.AlarmBitMap
492
493 am.onuAlarmManagerLock.Lock()
494 am.onuDBCopy[meAlarmKey{
495 classID: meClassID,
496 instanceID: meEntityID,
497 }] = meAlarmBitMap
498 am.onuAlarmManagerLock.Unlock()
499
500 am.IncrementAlarmUploadSeqNo()
501 }
502 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000503 am.onuAlarmManagerLock.RLock()
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000504 if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000505 am.onuAlarmManagerLock.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000506 if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000507 log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
Himani Chawlad3dac422021-03-13 02:31:31 +0530508 // Transition to failure
509 go failureTransition()
510 } //TODO: needs to handle timeouts
511 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000512 am.onuAlarmManagerLock.RUnlock()
Himani Chawlad3dac422021-03-13 02:31:31 +0530513 if am.isAlarmDBDiffPresent(ctx) {
514 // transition to resync state
515 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 if err := am.AlarmSyncFsm.PFsm.Event(AsEvResync); err != nil {
517 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 +0530518 }
519 }()
520 } else {
521 // Transition to sync state
522 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 if err := am.AlarmSyncFsm.PFsm.Event(AsEvSuccess); err != nil {
524 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 +0530525 }
526 }()
527 }
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530528
Himani Chawlad3dac422021-03-13 02:31:31 +0530529 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530530}
531
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532// StartOMCIAlarmMessageProcessing - TODO: add comment: add comment
533func (am *OnuAlarmManager) StartOMCIAlarmMessageProcessing(ctx context.Context) {
534 logger.Infow(ctx, "alarm-manager-start-omci-alarm-message-processing-routines", log.Fields{"device-id": am.deviceID})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530535 am.onuAlarmManagerLock.Lock()
536 am.processMessage = true
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530537 if am.activeAlarms == nil {
538 am.activeAlarms = make(map[alarmInfo]struct{})
539 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530540 am.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000541 // when instantiating alarm manager it was too early, but now we can check for ONU's extended OMCI support
542 am.isExtendedOmci = am.pOnuDeviceEntry.GetPersIsExtOmciSupported()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530543 am.onuAlarmManagerLock.Unlock()
Himani Chawla1472c682021-03-17 17:11:14 +0530544 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
545
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 if am.AlarmSyncFsm.PFsm.Is(asStDisabled) {
547 if err := am.AlarmSyncFsm.PFsm.Event(AsEvStart); err != nil {
548 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 +0530549 return
550 }
551 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 logger.Errorw(ctx, "wrong-state-of-alarm-sync-fsm-want-disabled", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current()),
553 "device-id": am.deviceID})
Himani Chawlad3dac422021-03-13 02:31:31 +0530554 return
555 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 logger.Debugw(ctx, "alarm-sync-fsm-started", log.Fields{"state": string(am.AlarmSyncFsm.PFsm.Current())})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530557}
558
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000559// HandleOmciAlarmNotificationMessage - TODO: add comment
560func (am *OnuAlarmManager) HandleOmciAlarmNotificationMessage(ctx context.Context, msg cmn.OmciMessage) {
561 logger.Debugw(ctx, "omci-alarm-notification-msg", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530562 "msg-type": msg.OmciMsg.MessageType})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530563
Himani Chawla7998aa92021-04-07 14:16:52 +0530564 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeAlarmNotification)
565 if msgLayer == nil {
566 logger.Errorw(ctx, "omci-msg-layer-could-not-be-detected-for-alarm-notification",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530568 return
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530569 }
Himani Chawla7998aa92021-04-07 14:16:52 +0530570 msgObj, msgOk := msgLayer.(*omci.AlarmNotificationMsg)
571 if !msgOk {
572 logger.Errorw(ctx, "omci-msg-layer-could-not-be-assigned-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
575 }
576 //Alarm Notification decoding at omci lib validates that the me class ID supports the
577 // alarm notifications.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 logger.Debugw(ctx, "alarm-notification-data-received", log.Fields{"device-id": am.deviceID, "data-fields": msgObj})
Himani Chawla7998aa92021-04-07 14:16:52 +0530579 if err := am.processAlarmData(ctx, msgObj); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 logger.Errorw(ctx, "unable-to-process-alarm-notification", log.Fields{"device-id": am.deviceID})
Himani Chawla7998aa92021-04-07 14:16:52 +0530581 }
582
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530583}
584
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585func (am *OnuAlarmManager) processAlarmData(ctx context.Context, msg *omci.AlarmNotificationMsg) error {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530586 classID := msg.EntityClass
587 sequenceNo := msg.AlarmSequenceNumber
588 meInstance := msg.EntityInstance
589 alarmBitmap := msg.AlarmBitmap
590 logger.Debugw(ctx, "processing-alarm-data", log.Fields{"class-id": classID, "instance-id": meInstance,
591 "alarmBitMap": alarmBitmap, "sequence-no": sequenceNo})
Himani Chawla7998aa92021-04-07 14:16:52 +0530592 am.onuAlarmManagerLock.Lock()
593 defer am.onuAlarmManagerLock.Unlock()
594 if !am.processMessage {
595 logger.Warnw(ctx, "ignoring-alarm-notification-received-for-me-as-channel-for-processing-is-closed",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000596 log.Fields{"device-id": am.deviceID})
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530597 return status.Error(codes.Unavailable, "alarm-manager-is-in-stopped-state")
Himani Chawla7998aa92021-04-07 14:16:52 +0530598 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 if _, present := am.pOnuDeviceEntry.GetOnuDB().MeDb[classID][meInstance]; !present {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000600 logger.Errorw(ctx, "me-class-instance-not-present",
601 log.Fields{"class-id": classID, "instance-id": meInstance, "device-id": am.deviceID})
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530602 return status.Error(codes.NotFound, "me-class-instance-not-present")
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530603 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530604 if sequenceNo > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 if am.AlarmSyncFsm.PFsm.Is(asStAuditing) || am.AlarmSyncFsm.PFsm.Is(asStResynchronizing) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530606 am.bufferedNotifications = append(am.bufferedNotifications, msg)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 logger.Debugw(ctx, "adding-notification-to-buffered-notification-list", log.Fields{"device-id": am.deviceID,
Himani Chawlad3dac422021-03-13 02:31:31 +0530608 "notification": msg})
609 return nil
Andrea Campanellace915292021-03-12 17:59:35 +0000610 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530611 am.incrementAlarmSequence()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612 if sequenceNo != am.lastAlarmSequence && am.pDeviceHandler.GetAlarmAuditInterval() > 0 {
Himani Chawlad3dac422021-03-13 02:31:31 +0530613 // signal early audit, if no match(if we are reaching here it means that audit is not going on currently)
614 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000615 if err := am.AlarmSyncFsm.PFsm.Event(AsEvAudit); err != nil {
616 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 +0530617 }
618 }()
619 }
620 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530621 entity, omciErr := me.LoadManagedEntityDefinition(classID,
622 me.ParamData{EntityID: meInstance})
623 if omciErr.StatusCode() != me.Success {
624 //log error and return
625 logger.Error(ctx, "unable-to-get-managed-entity", log.Fields{"class-id": classID, "instance-id": meInstance})
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530626 return status.Error(codes.NotFound, "unable-to-get-managed-entity")
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530627 }
628 meAlarmMap := entity.GetAlarmMap()
629 if meAlarmMap == nil {
630 logger.Error(ctx, "unable-to-get-managed-entity-alarm-map", log.Fields{"class-id": classID, "instance-id": meInstance})
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530631 return status.Error(codes.NotFound, "unable-to-get-managed-entity-alarm-map")
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530632 }
Himani Chawlad3dac422021-03-13 02:31:31 +0530633
634 am.alarmBitMapDB[meAlarmKey{
635 classID: classID,
636 instanceID: meInstance,
637 }] = alarmBitmap
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530638 // Loop over the supported alarm list for this me
639 for alarmNo := range meAlarmMap {
640 // Check if alarmNo was previously active in the alarms, if yes clear it and remove it from active alarms
641 _, exists := am.activeAlarms[alarmInfo{
642 classID: classID,
643 instanceID: meInstance,
644 alarmNo: alarmNo,
645 }]
646 if exists {
647 // Clear this alarm if It is cleared now, in that case IsAlarmClear would return true
648 cleared, err := msg.IsAlarmClear(alarmNo)
649 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000650 logger.Warnw(ctx, "unable-to-find-out-alarm-is-cleared", log.Fields{"device-id": am.deviceID,
651 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530652 return err
653 }
654 if cleared {
655 // Clear this alarm.
656 am.clearAlarm(ctx, classID, meInstance, alarmNo)
657 }
658 } else {
659 // If alarm entry was not present in the list of active alarms, we need to see if this alarm is now active
660 // or not, if yes then raise it.
661 raised, err := msg.IsAlarmActive(alarmNo)
662 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000663 logger.Warnw(ctx, "unable-to-find-out-alarm-is-raised", log.Fields{"device-id": am.deviceID,
664 "class-id": classID, "instance-id": meInstance, "alarm-no": alarmNo})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530665 return err
666 }
667 if raised {
668 am.raiseAlarm(ctx, classID, meInstance, alarmNo)
669 }
670 }
671 }
672 return nil
673}
674
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000675func (am *OnuAlarmManager) raiseAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530676 am.activeAlarms[alarmInfo{
677 classID: classID,
678 instanceID: instanceID,
679 alarmNo: alarm,
680 }] = struct{}{}
Himani Chawlad3dac422021-03-13 02:31:31 +0530681
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530682 go am.sendAlarm(ctx, classID, instanceID, alarm, true)
683}
684
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000685func (am *OnuAlarmManager) clearAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530686 go am.sendAlarm(ctx, classID, instanceID, alarm, false)
687 delete(am.activeAlarms, alarmInfo{
688 classID: classID,
689 instanceID: instanceID,
690 alarmNo: alarm,
691 })
Himani Chawlad3dac422021-03-13 02:31:31 +0530692 key := meAlarmKey{
693 classID: classID,
694 instanceID: instanceID,
695 }
696 if am.alarmBitMapDB[key] == [alarmBitMapSizeBytes]byte{0} {
697 delete(am.alarmBitMapDB, key)
698 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530699}
700
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000701func (am *OnuAlarmManager) getIntfIDAlarm(ctx context.Context, classID me.ClassID, instanceID uint16) *uint32 {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530702 var intfID *uint32
703 if classID == circuitPackClassID || classID == physicalPathTerminationPointEthernetUniClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000704 for _, uniPort := range *am.pDeviceHandler.GetUniEntityMap() {
705 if uniPort.EntityID == instanceID {
706 intfID = &uniPort.PortNo
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530707 return intfID
708 }
709 }
710 } else if classID == aniGClassID || classID == onuGClassID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000711 intfID = am.pDeviceHandler.GetPonPortNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530712 return intfID
713 } else {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000714 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 +0530715 }
716 return nil
717}
718
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000719func (am *OnuAlarmManager) sendAlarm(ctx context.Context, classID me.ClassID, instanceID uint16, alarm uint8, raised bool) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530720 context := make(map[string]string)
721 intfID := am.getIntfIDAlarm(ctx, classID, instanceID)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000722 onuID := am.deviceID
723 serialNo := am.pOnuDeviceEntry.GetPersSerialNumber()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530724 if intfID == nil {
725 logger.Warn(ctx, "intf-id-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
726 return
727 }
728 context["onu-intf-id"] = fmt.Sprintf("%d", *intfID)
729 context["onu-id"] = onuID
730 context["onu-serial-number"] = serialNo
731
ozgecanetsia2f05ed32021-05-31 17:13:48 +0300732 raisedTimestamp := time.Now().Unix()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530733 eventDetails, err := am.getDeviceEventData(ctx, classID, alarm)
734 if err != nil {
735 logger.Warn(ctx, "event-details-for-alarm-not-found", log.Fields{"alarm-no": alarm, "class-id": classID})
736 return
737 }
738 suffixDesc := "Raised"
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300739 clearOrRaiseEvent := "RAISE_EVENT"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530740 if !raised {
741 suffixDesc = "Cleared"
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300742 clearOrRaiseEvent = "CLEAR_EVENT"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530743 }
744 deviceEvent := &voltha.DeviceEvent{
745 ResourceId: onuID,
Marcos Aurelio Carrero (Furukawa)935e5f62023-11-13 14:18:35 -0300746 DeviceEventName: fmt.Sprintf("%s_%s", eventDetails.EventName, clearOrRaiseEvent),
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530747 Description: fmt.Sprintf("%s Event - %s - %s", eventDetails.EventDescription, eventDetails.EventName,
748 suffixDesc),
749 Context: context,
750 }
751 _ = am.eventProxy.SendDeviceEvent(ctx, deviceEvent, eventDetails.EventCategory, eventDetails.EventSubCategory,
752 raisedTimestamp)
753}
Himani Chawlad3dac422021-03-13 02:31:31 +0530754
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000755func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530756 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
757}
758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530760 //alarm sequence number wraps from 255 to 1.
761 if am.lastAlarmSequence == 255 {
762 am.lastAlarmSequence = 1
763 } else {
764 am.lastAlarmSequence++
765 }
766}
767
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000768func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530769 am.lastAlarmSequence = 0
770}
771
772// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000773func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530774 // flush alarm sync channel
775 select {
776 case <-am.eventChannel:
777 logger.Debug(ctx, "flushed-alarm-sync-channel")
778 default:
779 }
780 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000781 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530782 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
783 default:
784 }
785}
786
787// getDeviceEventData returns the event data for a device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000788func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530789 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
790 return onuEventDetails, nil
791 }
792 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
793}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000794
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530795// ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000796func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000797 am.onuAlarmManagerLock.Lock()
798 am.alarmUploadSeqNo = 0
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000799 am.alarmUploadNoOfCmdsOrMEs = 0
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000800 am.onuAlarmManagerLock.Unlock()
801}
802
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530803// IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000804func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000805 am.onuAlarmManagerLock.Lock()
806 am.alarmUploadSeqNo++
807 am.onuAlarmManagerLock.Unlock()
808}
809
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530810// GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000812 am.onuAlarmManagerLock.RLock()
813 value := am.alarmUploadSeqNo
814 am.onuAlarmManagerLock.RUnlock()
815 return value
816}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000817
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530818// GetAlarmMgrEventChannel gets alarm manager event channel
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
820 return am.eventChannel
821}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000822
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530823// GetOnuActiveAlarms - Fetch the Active Alarms on demand
824func (am *OnuAlarmManager) GetOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
825
826 am.onuAlarmRequestLock.Lock()
827 defer am.onuAlarmRequestLock.Unlock()
828
829 resp := extension.SingleGetValueResponse{
830 Response: &extension.GetValueResponse{
831 Status: extension.GetValueResponse_OK,
832 Response: &extension.GetValueResponse_OnuActiveAlarms{
833 OnuActiveAlarms: &extension.GetOnuOmciActiveAlarmsResponse{},
834 },
835 },
836 }
837
838 logger.Debugw(ctx, "Requesting to start audit on demand ", log.Fields{"device-id": am.deviceID})
839 am.isAsyncAlarmRequest = true
840
841 am.AsyncAlarmsCommChan <- struct{}{}
842
843 select {
844 case <-time.After(10 * time.Second): //the time to wait needs further discussion.
845 logger.Errorw(ctx, "Couldn't get the Alarms with in 10 seconds stipulated time frame ", log.Fields{"device-id": am.deviceID})
846 am.isAsyncAlarmRequest = false
847
848 case <-am.AsyncAlarmsCommChan:
849 logger.Debugw(ctx, "Received response for the alarm audit ", log.Fields{"device-id": am.deviceID})
850
851 }
852
853 for activeAlarm := range am.activeAlarms {
854
855 onuEventDetails := am.onuEventsList[onuDevice{classID: activeAlarm.classID, alarmno: activeAlarm.alarmNo}]
856 activeAlarmData := extension.AlarmData{}
857 activeAlarmData.ClassId = uint32(activeAlarm.classID)
858 activeAlarmData.InstanceId = uint32(activeAlarm.instanceID)
859 activeAlarmData.Name = onuEventDetails.EventName
860 activeAlarmData.Description = onuEventDetails.EventDescription
861
862 resp.Response.GetOnuActiveAlarms().ActiveAlarms = append(resp.Response.GetOnuActiveAlarms().ActiveAlarms, &activeAlarmData)
863
864 }
865
866 return &resp
867}
868
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000869// PrepareForGarbageCollection - remove references to prepare for garbage collection
870func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
871 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
872 am.pDeviceHandler = nil
873 am.pOnuDeviceEntry = nil
874}
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530875
876func (am *OnuAlarmManager) processOnuOnlyDifferences(ctx context.Context, failureTransition func()) error {
877 for alarm := range am.onuDBCopy {
878 if _, exists := am.oltDbCopy[meAlarmKey{classID: alarm.classID, instanceID: alarm.instanceID}]; !exists {
879 omciAlarmMessage := createOmciAlarmMessage(alarm, am.onuDBCopy[alarm])
880 if err := am.processAlarm(ctx, omciAlarmMessage, failureTransition); err != nil {
881 return err
882 }
883 }
884 }
885 return nil
886}
887
888func (am *OnuAlarmManager) processOltOnlyDifferences(ctx context.Context, failureTransition func()) error {
889 for alarm := range am.oltDbCopy {
890 if _, exists := am.onuDBCopy[meAlarmKey{classID: alarm.classID, instanceID: alarm.instanceID}]; !exists {
891 omciAlarmMessage := createOmciAlarmMessage(alarm, am.oltDbCopy[alarm])
892 if err := am.processAlarm(ctx, omciAlarmMessage, failureTransition); err != nil {
893 return err
894 }
895 }
896 }
897 return nil
898}
899
900func (am *OnuAlarmManager) processAttributeDifferences(ctx context.Context, failureTransition func()) error {
901 for alarm := range am.onuDBCopy {
902 if _, exists := am.oltDbCopy[alarm]; exists && am.onuDBCopy[alarm] != am.oltDbCopy[alarm] {
903 omciAlarmMessage := createOmciAlarmMessage(alarm, am.onuDBCopy[alarm])
904 if err := am.processAlarm(ctx, omciAlarmMessage, failureTransition); err != nil {
905 return err
906 }
907 }
908 }
909 return nil
910}
911
912func (am *OnuAlarmManager) processBufferedNotifications(ctx context.Context, failureTransition func()) error {
913 for _, notif := range am.bufferedNotifications {
914 logger.Debugw(ctx, "processing-buffered-alarm-notification", log.Fields{"device-id": am.deviceID, "notification": notif})
915 if err := am.processAlarm(ctx, notif, failureTransition); err != nil {
916 return err
917 }
918 }
919 return nil
920}
921
922func (am *OnuAlarmManager) processAlarm(ctx context.Context, omciAlarmMessage *omci.AlarmNotificationMsg, failureTransition func()) error {
923 // [https://jira.opencord.org/browse/VOL-5223]
924 //The following test scenarios cause AlarmMgr to get into a loop state.
925 //Test Scenario:
926 // - Unconfigured MEs being reported by vendor ONTs.
927 // - Undefined Alarm Bit Map (ONU-G ME for Example.)
928 // - MEs created by OLT as per G984.4 standard are not part of ONU DB.
929 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
930 if statusErr, ok := status.FromError(err); ok {
931 switch statusErr.Code() {
932 case codes.NotFound:
933 logger.Warnw(ctx, "ME Instance or ME Alarm Map not found in ONUDB", log.Fields{"device-id": am.deviceID, "Error": err})
934 case codes.Unavailable:
935 logger.Warnw(ctx, "Alarm Mgr is stopped, stop further processing", log.Fields{"device-id": am.deviceID, "Error": err})
936 return err
937 default:
938 logger.Errorw(ctx, "Unexpected error", log.Fields{"device-id": am.deviceID, "Error": err})
939 go failureTransition()
940 return err
941 }
942 }
943 }
944 return nil
945}
946
947func createOmciAlarmMessage(alarm meAlarmKey, alarmBitmap [alarmBitMapSizeBytes]byte) *omci.AlarmNotificationMsg {
948 return &omci.AlarmNotificationMsg{
949 MeBasePacket: omci.MeBasePacket{
950 EntityClass: alarm.classID,
951 EntityInstance: alarm.instanceID,
952 },
953 AlarmBitmap: alarmBitmap,
954 }
955}