blob: 13a3bef91a7eabee7c85aecc665cc922d581c284 [file] [log] [blame]
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2021-2024 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
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +053093 EventDescription string
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053094 EventCategory eventif.EventCategory
95 EventSubCategory eventif.EventSubCategory
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053096}
97
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000098// OnuAlarmManager holds alarm manager related data
99type OnuAlarmManager struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000100 pDeviceHandler cmn.IdeviceHandler
101 pOnuDeviceEntry cmn.IonuDeviceEntry
102 eventProxy eventif.EventProxy
103 StopProcessingOmciMessages chan bool
104 eventChannel chan cmn.Message
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000105 activeAlarms alarms
106 alarmBitMapDB alarmBitMapDB
107 onuEventsList map[onuDevice]onuDeviceEvent
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000108 AlarmSyncFsm *cmn.AdapterFsm
109 oltDbCopy alarmBitMapDB
110 onuDBCopy alarmBitMapDB
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530111 StopAlarmAuditTimer chan struct{}
112 AsyncAlarmsCommChan chan struct{}
113 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000114 bufferedNotifications []*omci.AlarmNotificationMsg
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530115 onuAlarmManagerLock sync.RWMutex
116 onuAlarmRequestLock sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117 alarmUploadSeqNo uint16
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000118 alarmUploadNoOfCmdsOrMEs uint16
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530119 processMessage bool
120 lastAlarmSequence uint8
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000121 isExtendedOmci bool
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530122 isAsyncAlarmRequest bool
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 }
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +0530599 if meAttributes := am.pOnuDeviceEntry.GetOnuDB().GetMe(classID, meInstance); meAttributes == nil {
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
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530755//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000756func (am *OnuAlarmManager) isAlarmDBDiffPresent(ctx context.Context) bool {
Himani Chawlad3dac422021-03-13 02:31:31 +0530757 return !reflect.DeepEqual(am.onuDBCopy, am.oltDbCopy)
758}
759
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000760func (am *OnuAlarmManager) incrementAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530761 //alarm sequence number wraps from 255 to 1.
762 if am.lastAlarmSequence == 255 {
763 am.lastAlarmSequence = 1
764 } else {
765 am.lastAlarmSequence++
766 }
767}
768
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000769func (am *OnuAlarmManager) resetAlarmSequence() {
Himani Chawlad3dac422021-03-13 02:31:31 +0530770 am.lastAlarmSequence = 0
771}
772
773// flushAlarmSyncChannels flushes all alarm sync channels to discard any previous response
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000774func (am *OnuAlarmManager) flushAlarmSyncChannels(ctx context.Context) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530775 // flush alarm sync channel
776 select {
777 case <-am.eventChannel:
778 logger.Debug(ctx, "flushed-alarm-sync-channel")
779 default:
780 }
781 select {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000782 case <-am.StopAlarmAuditTimer:
Himani Chawlad3dac422021-03-13 02:31:31 +0530783 logger.Debug(ctx, "flushed-alarm-audit-timer-channel")
784 default:
785 }
786}
787
788// getDeviceEventData returns the event data for a device
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530789//
790//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791func (am *OnuAlarmManager) getDeviceEventData(ctx context.Context, classID me.ClassID, alarmNo uint8) (onuDeviceEvent, error) {
Himani Chawlad3dac422021-03-13 02:31:31 +0530792 if onuEventDetails, ok := am.onuEventsList[onuDevice{classID: classID, alarmno: alarmNo}]; ok {
793 return onuEventDetails, nil
794 }
795 return onuDeviceEvent{}, errors.New("onu Event Detail not found")
796}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000797
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530798// ResetAlarmUploadCounters resets alarm upload sequence number and number of commands
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000799func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000800 am.onuAlarmManagerLock.Lock()
801 am.alarmUploadSeqNo = 0
Holger Hildebrandt3b29a8a2022-07-11 05:55:13 +0000802 am.alarmUploadNoOfCmdsOrMEs = 0
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000803 am.onuAlarmManagerLock.Unlock()
804}
805
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530806// IncrementAlarmUploadSeqNo increments alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000807func (am *OnuAlarmManager) IncrementAlarmUploadSeqNo() {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000808 am.onuAlarmManagerLock.Lock()
809 am.alarmUploadSeqNo++
810 am.onuAlarmManagerLock.Unlock()
811}
812
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530813// GetAlarmUploadSeqNo gets alarm upload sequence number
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814func (am *OnuAlarmManager) GetAlarmUploadSeqNo() uint16 {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000815 am.onuAlarmManagerLock.RLock()
816 value := am.alarmUploadSeqNo
817 am.onuAlarmManagerLock.RUnlock()
818 return value
819}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530821// GetAlarmMgrEventChannel gets alarm manager event channel
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822func (am *OnuAlarmManager) GetAlarmMgrEventChannel() chan cmn.Message {
823 return am.eventChannel
824}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000825
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530826// GetOnuActiveAlarms - Fetch the Active Alarms on demand
827func (am *OnuAlarmManager) GetOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
828
829 am.onuAlarmRequestLock.Lock()
830 defer am.onuAlarmRequestLock.Unlock()
831
832 resp := extension.SingleGetValueResponse{
833 Response: &extension.GetValueResponse{
834 Status: extension.GetValueResponse_OK,
835 Response: &extension.GetValueResponse_OnuActiveAlarms{
836 OnuActiveAlarms: &extension.GetOnuOmciActiveAlarmsResponse{},
837 },
838 },
839 }
840
841 logger.Debugw(ctx, "Requesting to start audit on demand ", log.Fields{"device-id": am.deviceID})
842 am.isAsyncAlarmRequest = true
843
844 am.AsyncAlarmsCommChan <- struct{}{}
845
846 select {
847 case <-time.After(10 * time.Second): //the time to wait needs further discussion.
848 logger.Errorw(ctx, "Couldn't get the Alarms with in 10 seconds stipulated time frame ", log.Fields{"device-id": am.deviceID})
849 am.isAsyncAlarmRequest = false
850
851 case <-am.AsyncAlarmsCommChan:
852 logger.Debugw(ctx, "Received response for the alarm audit ", log.Fields{"device-id": am.deviceID})
853
854 }
855
856 for activeAlarm := range am.activeAlarms {
857
858 onuEventDetails := am.onuEventsList[onuDevice{classID: activeAlarm.classID, alarmno: activeAlarm.alarmNo}]
859 activeAlarmData := extension.AlarmData{}
860 activeAlarmData.ClassId = uint32(activeAlarm.classID)
861 activeAlarmData.InstanceId = uint32(activeAlarm.instanceID)
862 activeAlarmData.Name = onuEventDetails.EventName
863 activeAlarmData.Description = onuEventDetails.EventDescription
864
865 resp.Response.GetOnuActiveAlarms().ActiveAlarms = append(resp.Response.GetOnuActiveAlarms().ActiveAlarms, &activeAlarmData)
866
867 }
868
869 return &resp
870}
871
Holger Hildebrandte7cc6092022-02-01 11:37:03 +0000872// PrepareForGarbageCollection - remove references to prepare for garbage collection
873func (am *OnuAlarmManager) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
874 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
875 am.pDeviceHandler = nil
876 am.pOnuDeviceEntry = nil
877}
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530878
879func (am *OnuAlarmManager) processOnuOnlyDifferences(ctx context.Context, failureTransition func()) error {
880 for alarm := range am.onuDBCopy {
881 if _, exists := am.oltDbCopy[meAlarmKey{classID: alarm.classID, instanceID: alarm.instanceID}]; !exists {
882 omciAlarmMessage := createOmciAlarmMessage(alarm, am.onuDBCopy[alarm])
883 if err := am.processAlarm(ctx, omciAlarmMessage, failureTransition); err != nil {
884 return err
885 }
886 }
887 }
888 return nil
889}
890
891func (am *OnuAlarmManager) processOltOnlyDifferences(ctx context.Context, failureTransition func()) error {
892 for alarm := range am.oltDbCopy {
893 if _, exists := am.onuDBCopy[meAlarmKey{classID: alarm.classID, instanceID: alarm.instanceID}]; !exists {
894 omciAlarmMessage := createOmciAlarmMessage(alarm, am.oltDbCopy[alarm])
895 if err := am.processAlarm(ctx, omciAlarmMessage, failureTransition); err != nil {
896 return err
897 }
898 }
899 }
900 return nil
901}
902
903func (am *OnuAlarmManager) processAttributeDifferences(ctx context.Context, failureTransition func()) error {
904 for alarm := range am.onuDBCopy {
905 if _, exists := am.oltDbCopy[alarm]; exists && am.onuDBCopy[alarm] != am.oltDbCopy[alarm] {
906 omciAlarmMessage := createOmciAlarmMessage(alarm, am.onuDBCopy[alarm])
907 if err := am.processAlarm(ctx, omciAlarmMessage, failureTransition); err != nil {
908 return err
909 }
910 }
911 }
912 return nil
913}
914
915func (am *OnuAlarmManager) processBufferedNotifications(ctx context.Context, failureTransition func()) error {
916 for _, notif := range am.bufferedNotifications {
917 logger.Debugw(ctx, "processing-buffered-alarm-notification", log.Fields{"device-id": am.deviceID, "notification": notif})
918 if err := am.processAlarm(ctx, notif, failureTransition); err != nil {
919 return err
920 }
921 }
922 return nil
923}
924
925func (am *OnuAlarmManager) processAlarm(ctx context.Context, omciAlarmMessage *omci.AlarmNotificationMsg, failureTransition func()) error {
926 // [https://jira.opencord.org/browse/VOL-5223]
927 //The following test scenarios cause AlarmMgr to get into a loop state.
928 //Test Scenario:
929 // - Unconfigured MEs being reported by vendor ONTs.
930 // - Undefined Alarm Bit Map (ONU-G ME for Example.)
931 // - MEs created by OLT as per G984.4 standard are not part of ONU DB.
932 if err := am.processAlarmData(ctx, omciAlarmMessage); err != nil {
933 if statusErr, ok := status.FromError(err); ok {
934 switch statusErr.Code() {
935 case codes.NotFound:
936 logger.Warnw(ctx, "ME Instance or ME Alarm Map not found in ONUDB", log.Fields{"device-id": am.deviceID, "Error": err})
937 case codes.Unavailable:
938 logger.Warnw(ctx, "Alarm Mgr is stopped, stop further processing", log.Fields{"device-id": am.deviceID, "Error": err})
939 return err
940 default:
941 logger.Errorw(ctx, "Unexpected error", log.Fields{"device-id": am.deviceID, "Error": err})
942 go failureTransition()
943 return err
944 }
945 }
946 }
947 return nil
948}
949
950func createOmciAlarmMessage(alarm meAlarmKey, alarmBitmap [alarmBitMapSizeBytes]byte) *omci.AlarmNotificationMsg {
951 return &omci.AlarmNotificationMsg{
952 MeBasePacket: omci.MeBasePacket{
953 EntityClass: alarm.classID,
954 EntityInstance: alarm.instanceID,
955 },
956 AlarmBitmap: alarmBitmap,
957 }
958}