blob: 8cbc2434617bb7046f77e3a51f5820c411715aef [file] [log] [blame]
Abhilash S.L765ad002019-04-24 16:40:57 +05301/*
Joey Armstrong11f5a572024-01-12 19:11:32 -05002 * Copyright 2019-2024 Open Networking Foundation (ONF) and the ONF Contributors
Abhilash S.L765ad002019-04-24 16:40:57 +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 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Joey Armstrong3f0e2422023-07-05 18:25:41 -040017// Package core provides the utility for olt devices, flows and statistics
Scott Bakerdbd960e2020-02-28 08:57:51 -080018package core
Abhilash S.L765ad002019-04-24 16:40:57 +053019
20import (
kesavand62126212021-01-12 04:56:06 -050021 "container/list"
Neha Sharma96b7bf22020-06-15 10:37:32 +000022 "context"
Abhilash S.L765ad002019-04-24 16:40:57 +053023 "fmt"
Shrey Baid26912972020-04-16 21:02:31 +053024 "sync"
25 "time"
26
Mahir Gunyel85f61c12021-10-06 11:53:45 -070027 plt "github.com/opencord/voltha-lib-go/v7/pkg/platform"
khenaidoo106c61a2021-08-11 18:05:46 -040028 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
29
30 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Thomas Lee S94109f12020-03-03 16:39:29 +053031 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Akash Reddy Kankanalac6b6ca12025-06-12 14:26:57 +053032 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo106c61a2021-08-11 18:05:46 -040033 "github.com/opencord/voltha-protos/v5/go/extension"
34 "github.com/opencord/voltha-protos/v5/go/openolt"
35 "github.com/opencord/voltha-protos/v5/go/voltha"
Abhilash S.L765ad002019-04-24 16:40:57 +053036)
37
Gamze Abakafcbd6e72020-12-17 13:25:16 +000038const (
Akash Kankanala041a2122024-10-16 15:49:22 +053039 // NNIStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000040 NNIStats = "NNIStats"
Akash Kankanala041a2122024-10-16 15:49:22 +053041 // PONStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000042 PONStats = "PONStats"
Akash Kankanala041a2122024-10-16 15:49:22 +053043 // ONUStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000044 ONUStats = "ONUStats"
Akash Kankanala041a2122024-10-16 15:49:22 +053045 // GEMStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000046 GEMStats = "GEMStats"
47
Akash Kankanala041a2122024-10-16 15:49:22 +053048 // RxBytes constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000049 RxBytes = "RxBytes"
Akash Kankanala041a2122024-10-16 15:49:22 +053050 // RxPackets constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000051 RxPackets = "RxPackets"
Akash Kankanala041a2122024-10-16 15:49:22 +053052 // TxBytes constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000053 TxBytes = "TxBytes"
Akash Kankanala041a2122024-10-16 15:49:22 +053054 // TxPackets constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000055 TxPackets = "TxPackets"
Akash Kankanala041a2122024-10-16 15:49:22 +053056 // FecCodewords constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000057 FecCodewords = "FecCodewords"
Akash Kankanala041a2122024-10-16 15:49:22 +053058 // BipUnits constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000059 BipUnits = "BipUnits"
Akash Kankanala041a2122024-10-16 15:49:22 +053060 // BipErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000061 BipErrors = "BipErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053062 // RxPloamsNonIdle constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000063 RxPloamsNonIdle = "RxPloamsNonIdle"
Akash Kankanala041a2122024-10-16 15:49:22 +053064 // RxPloamsError constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000065 RxPloamsError = "RxPloamsError"
Akash Kankanala041a2122024-10-16 15:49:22 +053066 // RxOmci constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000067 RxOmci = "RxOmci"
Akash Kankanala041a2122024-10-16 15:49:22 +053068 // RxOmciPacketsCrcError constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000069 RxOmciPacketsCrcError = "RxOmciPacketsCrcError"
Akash Kankanala041a2122024-10-16 15:49:22 +053070 // PositiveDrift constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000071 PositiveDrift = "PositiveDrift"
Akash Kankanala041a2122024-10-16 15:49:22 +053072 // NegativeDrift constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000073 NegativeDrift = "NegativeDrift"
Akash Kankanala041a2122024-10-16 15:49:22 +053074 // DelimiterMissDetection constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000075 DelimiterMissDetection = "DelimiterMissDetection"
Akash Kankanala041a2122024-10-16 15:49:22 +053076 // FecCorrectedSymbols constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000077 FecCorrectedSymbols = "FecCorrectedSymbols"
Akash Kankanala041a2122024-10-16 15:49:22 +053078 // FecCodewordsCorrected constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000079 FecCodewordsCorrected = "FecCodewordsCorrected"
Akash Kankanala041a2122024-10-16 15:49:22 +053080 // fecCodewordsUncorrectable constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000081 fecCodewordsUncorrectable = "fec_codewords_uncorrectable"
Akash Kankanala041a2122024-10-16 15:49:22 +053082 // FecCorrectedUnits constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000083 FecCorrectedUnits = "FecCorrectedUnits"
Akash Kankanala041a2122024-10-16 15:49:22 +053084 // XGEMKeyErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000085 XGEMKeyErrors = "XGEMKeyErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053086 // XGEMLoss constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000087 XGEMLoss = "XGEMLOSS"
Akash Kankanala041a2122024-10-16 15:49:22 +053088 // BerReported constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000089 BerReported = "BerReported"
Akash Kankanala041a2122024-10-16 15:49:22 +053090 // LcdgErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000091 LcdgErrors = "LcdgErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053092 // RdiErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000093 RdiErrors = "RdiErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053094 // Timestamp constant
Himani Chawla2c8ae0f2021-05-18 23:27:00 +053095 Timestamp = "Timestamp"
Gamze Abakafcbd6e72020-12-17 13:25:16 +000096)
97
Naga Manjunath7615e552019-10-11 22:35:47 +053098var mutex = &sync.Mutex{}
99
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000100var onuStats = make(chan *openolt.OnuStatistics, 100)
101var gemStats = make(chan *openolt.GemPortStatistics, 100)
102
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400103// statRegInfo is used to register for notifications
104// on receiving port stats and flow stats indication
kesavand62126212021-01-12 04:56:06 -0500105type statRegInfo struct {
106 chn chan bool
107 portNo uint32
108 portType extension.GetOltPortCounters_PortType
109}
110
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700111// PonPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530112type PonPort struct {
Abhilash S.L765ad002019-04-24 16:40:57 +0530113 ONUs map[uint32]interface{}
114 ONUsByID map[uint32]interface{}
115
Akash Kankanala041a2122024-10-16 15:49:22 +0530116 DeviceID string
117 Label string
118
Abhilash S.L765ad002019-04-24 16:40:57 +0530119 RxBytes uint64
120 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000121 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530122 RxMcastPackets uint64
123 RxBcastPackets uint64
124 RxErrorPackets uint64
125 TxBytes uint64
126 TxPackets uint64
127 TxUcastPackets uint64
128 TxMcastPackets uint64
129 TxBcastPackets uint64
130 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000131 RxCrcErrors uint64
132 BipErrors uint64
Akash Kankanala041a2122024-10-16 15:49:22 +0530133 /*
134 This is a highly reduced version taken from the adtran pon_port.
135 TODO: Extend for use in the openolt adapter set.
136 */
137 /* MAX_ONUS_SUPPORTED = 256
138 DEFAULT_ENABLED = False
139 MAX_DEPLOYMENT_RANGE = 25000 # Meters (OLT-PB maximum)
140
141 _MCAST_ONU_ID = 253
142 _MCAST_ALLOC_BASE = 0x500
143
144 _SUPPORTED_ACTIVATION_METHODS = ['autodiscovery'] # , 'autoactivate']
145 _SUPPORTED_AUTHENTICATION_METHODS = ['serial-number']
146 */
147 PONID uint32
148 IntfID uint32
149 PortNum uint32
150 PortID uint32
Abhilash S.L765ad002019-04-24 16:40:57 +0530151}
152
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700153// NewPONPort returns a new instance of PonPort initialized with given PONID, DeviceID, IntfID and PortNum
Abhilash S.L765ad002019-04-24 16:40:57 +0530154func NewPONPort(PONID uint32, DeviceID string, IntfID uint32, PortNum uint32) *PonPort {
Abhilash S.L765ad002019-04-24 16:40:57 +0530155 var PON PonPort
156
157 PON.PONID = PONID
158 PON.DeviceID = DeviceID
159 PON.IntfID = IntfID
160 PON.PortNum = PortNum
161 PON.PortID = 0
Naga Manjunath7615e552019-10-11 22:35:47 +0530162 PON.Label = fmt.Sprintf("%s%d", "pon-", PONID)
Abhilash S.L765ad002019-04-24 16:40:57 +0530163
164 PON.ONUs = make(map[uint32]interface{})
165 PON.ONUsByID = make(map[uint32]interface{})
166
167 /*
168 Statistics taken from nni_port
169 self.intf_id = 0 #handled by getter
170 self.port_no = 0 #handled by getter
171 self.port_id = 0 #handled by getter
172
173 Note: In the current implementation of the kpis coming from the BAL the stats are the
174 samne model for NNI and PON.
175
176 TODO: Integrate additional kpis for the PON and other southbound port objecgts.
177
178 */
179
180 PON.RxBytes = 0
181 PON.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000182 PON.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530183 PON.RxMcastPackets = 0
184 PON.RxBcastPackets = 0
185 PON.RxErrorPackets = 0
186 PON.TxBytes = 0
187 PON.TxPackets = 0
188 PON.TxUcastPackets = 0
189 PON.TxMcastPackets = 0
190 PON.TxBcastPackets = 0
191 PON.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000192 PON.RxCrcErrors = 0
193 PON.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530194
195 /* def __str__(self):
196 return "PonPort-{}: Admin: {}, Oper: {}, OLT: {}".format(self._label,
197 self._admin_state,
198 self._oper_status,
199 self.olt)
200 */
201 return &PON
202}
203
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700204// NniPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530205type NniPort struct {
Akash Kankanala041a2122024-10-16 15:49:22 +0530206 Name string
Abhilash S.L765ad002019-04-24 16:40:57 +0530207
208 RxBytes uint64
209 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000210 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530211 RxMcastPackets uint64
212 RxBcastPackets uint64
213 RxErrorPackets uint64
214 TxBytes uint64
215 TxPackets uint64
216 TxUcastPackets uint64
217 TxMcastPackets uint64
218 TxBcastPackets uint64
219 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000220 RxCrcErrors uint64
221 BipErrors uint64
Akash Kankanala041a2122024-10-16 15:49:22 +0530222 /*
223 Northbound network port, often Ethernet-based
224
225 This is a highly reduced version taken from the adtran nni_port code set
226 TODO: add functions to allow for port specific values and operations
227 */
228 PortNum uint32
229 LogicalPort uint32
230 IntfID uint32
Abhilash S.L765ad002019-04-24 16:40:57 +0530231}
232
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700233// NewNniPort returns a new instance of NniPort initialized with the given PortNum and IntfID
Abhilash S.L765ad002019-04-24 16:40:57 +0530234func NewNniPort(PortNum uint32, IntfID uint32) *NniPort {
Abhilash S.L765ad002019-04-24 16:40:57 +0530235 var NNI NniPort
236
237 NNI.PortNum = PortNum
Naga Manjunath7615e552019-10-11 22:35:47 +0530238 NNI.Name = fmt.Sprintf("%s%d", "nni-", PortNum)
Abhilash S.L765ad002019-04-24 16:40:57 +0530239 NNI.IntfID = IntfID
240
241 NNI.RxBytes = 0
242 NNI.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000243 NNI.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530244 NNI.RxMcastPackets = 0
245 NNI.RxBcastPackets = 0
246 NNI.RxErrorPackets = 0
247 NNI.TxBytes = 0
248 NNI.TxPackets = 0
249 NNI.TxUcastPackets = 0
250 NNI.TxMcastPackets = 0
251 NNI.TxBcastPackets = 0
252 NNI.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000253 NNI.RxCrcErrors = 0
254 NNI.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530255
256 return &NNI
257}
258
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400259// StatType defines portStatsType and flowStatsType types
kesavand62126212021-01-12 04:56:06 -0500260type StatType int
261
262const (
263 portStatsType StatType = iota
264 flowStatsType
265)
266
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700267// OpenOltStatisticsMgr structure
Abhilash S.L765ad002019-04-24 16:40:57 +0530268type OpenOltStatisticsMgr struct {
Akash Kankanala041a2122024-10-16 15:49:22 +0530269 Device *DeviceHandler
270 NorthBoundPort map[uint32]*NniPort
271 SouthBoundPort map[uint32]*PonPort
272 statIndListners map[StatType]*list.List
Abhilash S.L765ad002019-04-24 16:40:57 +0530273 // TODO PMMetrics Metrics
Akash Kankanala041a2122024-10-16 15:49:22 +0530274 // statIndListners is the list of requests to be notified when port and flow stats indication is received
kesavand62126212021-01-12 04:56:06 -0500275 statIndListnerMu sync.Mutex
Abhilash S.L765ad002019-04-24 16:40:57 +0530276}
277
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700278// NewOpenOltStatsMgr returns a new instance of the OpenOltStatisticsMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000279func NewOpenOltStatsMgr(ctx context.Context, Dev *DeviceHandler) *OpenOltStatisticsMgr {
Abhilash S.L765ad002019-04-24 16:40:57 +0530280 var StatMgr OpenOltStatisticsMgr
281
282 StatMgr.Device = Dev
283 // TODO call metric PMMetric =
284 // Northbound and Southbound ports
285 // added to initialize the pm_metrics
286 var Ports interface{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000287 Ports, _ = InitPorts(ctx, "nni", Dev.device.Id, 1)
Naga Manjunath7615e552019-10-11 22:35:47 +0530288 StatMgr.NorthBoundPort, _ = Ports.(map[uint32]*NniPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700289 NumPonPorts := Dev.resourceMgr[0].DevInfo.GetPonPorts()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000290 Ports, _ = InitPorts(ctx, "pon", Dev.device.Id, NumPonPorts)
Naga Manjunath7615e552019-10-11 22:35:47 +0530291 StatMgr.SouthBoundPort, _ = Ports.(map[uint32]*PonPort)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000292 if StatMgr.Device.openOLT.enableONUStats {
293 go StatMgr.publishOnuStats()
294 }
295 if StatMgr.Device.openOLT.enableGemStats {
296 go StatMgr.publishGemStats()
297 }
kesavand62126212021-01-12 04:56:06 -0500298 StatMgr.statIndListners = make(map[StatType]*list.List)
299 StatMgr.statIndListners[portStatsType] = list.New()
300 StatMgr.statIndListners[flowStatsType] = list.New()
Abhilash S.L765ad002019-04-24 16:40:57 +0530301 return &StatMgr
302}
303
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700304// InitPorts collects the port objects: nni and pon that are updated with the current data from the OLT
Neha Sharma96b7bf22020-06-15 10:37:32 +0000305func InitPorts(ctx context.Context, Intftype string, DeviceID string, numOfPorts uint32) (interface{}, error) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530306 /*
307 This method collects the port objects: nni and pon that are updated with the
308 current data from the OLT
309
310 Both the northbound (nni) and southbound ports are indexed by the interface id (intf_id)
311 and NOT the port number. When the port object is instantiated it will contain the intf_id and
312 port_no values
313
314 :param type:
315 :return:
316 */
317 var i uint32
318 if Intftype == "nni" {
Naga Manjunath7615e552019-10-11 22:35:47 +0530319 NniPorts := make(map[uint32]*NniPort)
320 for i = 0; i < numOfPorts; i++ {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000321 Port := BuildPortObject(ctx, i, "nni", DeviceID).(*NniPort)
Naga Manjunath7615e552019-10-11 22:35:47 +0530322 NniPorts[Port.IntfID] = Port
Abhilash S.L765ad002019-04-24 16:40:57 +0530323 }
324 return NniPorts, nil
325 } else if Intftype == "pon" {
Naga Manjunath7615e552019-10-11 22:35:47 +0530326 PONPorts := make(map[uint32]*PonPort)
327 for i = 0; i < numOfPorts; i++ {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000328 PONPort := BuildPortObject(ctx, i, "pon", DeviceID).(*PonPort)
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700329 PONPorts[plt.PortNoToIntfID(PONPort.IntfID, voltha.Port_PON_OLT)] = PONPort
Abhilash S.L765ad002019-04-24 16:40:57 +0530330 }
331 return PONPorts, nil
332 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000333 logger.Errorw(ctx, "invalid-type-of-interface", log.Fields{"interface-type": Intftype})
Thomas Lee S94109f12020-03-03 16:39:29 +0530334 return nil, olterrors.NewErrInvalidValue(log.Fields{"interface-type": Intftype}, nil)
Abhilash S.L765ad002019-04-24 16:40:57 +0530335 }
336}
337
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700338// BuildPortObject allows for updating north and southbound ports, newly discovered ports, and devices
Neha Sharma96b7bf22020-06-15 10:37:32 +0000339func BuildPortObject(ctx context.Context, PortNum uint32, IntfType string, DeviceID string) interface{} {
Abhilash S.L765ad002019-04-24 16:40:57 +0530340 /*
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700341 Separate method to allow for updating north and southbound ports
Abhilash S.L765ad002019-04-24 16:40:57 +0530342 newly discovered ports and devices
343
344 :param port_num:
345 :param type:
346 :return:
347 */
348
Akash Kankanala041a2122024-10-16 15:49:22 +0530349 // This builds a port object which is added to the
350 // appropriate northbound or southbound values
Abhilash S.L765ad002019-04-24 16:40:57 +0530351 if IntfType == "nni" {
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700352 IntfID := plt.IntfIDToPortNo(PortNum, voltha.Port_ETHERNET_NNI)
353 nniID := plt.PortNoToIntfID(IntfID, voltha.Port_ETHERNET_NNI)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000354 logger.Debugw(ctx, "interface-type-nni",
Shrey Baid26912972020-04-16 21:02:31 +0530355 log.Fields{
356 "nni-id": nniID,
357 "intf-type": IntfType})
Naga Manjunath7615e552019-10-11 22:35:47 +0530358 return NewNniPort(PortNum, nniID)
Abhilash S.L765ad002019-04-24 16:40:57 +0530359 } else if IntfType == "pon" {
360 // PON ports require a different configuration
361 // intf_id and pon_id are currently equal.
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700362 IntfID := plt.IntfIDToPortNo(PortNum, voltha.Port_PON_OLT)
363 PONID := plt.PortNoToIntfID(IntfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000364 logger.Debugw(ctx, "interface-type-pon",
Shrey Baid26912972020-04-16 21:02:31 +0530365 log.Fields{
366 "pon-id": PONID,
367 "intf-type": IntfType})
Abhilash S.L765ad002019-04-24 16:40:57 +0530368 return NewPONPort(PONID, DeviceID, IntfID, PortNum)
369 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000370 logger.Errorw(ctx, "invalid-type-of-interface", log.Fields{"intf-type": IntfType})
Abhilash S.L765ad002019-04-24 16:40:57 +0530371 return nil
372 }
373}
374
Naga Manjunath7615e552019-10-11 22:35:47 +0530375// collectNNIMetrics will collect the nni port metrics
376func (StatMgr *OpenOltStatisticsMgr) collectNNIMetrics(nniID uint32) map[string]float32 {
Naga Manjunath7615e552019-10-11 22:35:47 +0530377 nnival := make(map[string]float32)
378 mutex.Lock()
379 cm := StatMgr.Device.portStats.NorthBoundPort[nniID]
380 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000381 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530382
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000383 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400384 for metric := range metricNames {
385 if metricNames[metric].Enabled {
386 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530387 }
388 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000389
390 for _, mName := range metrics {
391 switch mName {
392 case "rx_bytes":
393 nnival["RxBytes"] = float32(cm.RxBytes)
394 case "rx_packets":
395 nnival["RxPackets"] = float32(cm.RxPackets)
396 case "rx_ucast_packets":
397 nnival["RxUcastPackets"] = float32(cm.RxUcastPackets)
398 case "rx_mcast_packets":
399 nnival["RxMcastPackets"] = float32(cm.RxMcastPackets)
400 case "rx_bcast_packets":
401 nnival["RxBcastPackets"] = float32(cm.RxBcastPackets)
402 case "tx_bytes":
403 nnival["TxBytes"] = float32(cm.TxBytes)
404 case "tx_packets":
405 nnival["TxPackets"] = float32(cm.TxPackets)
406 case "tx_mcast_packets":
407 nnival["TxMcastPackets"] = float32(cm.TxMcastPackets)
408 case "tx_bcast_packets":
409 nnival["TxBcastPackets"] = float32(cm.TxBcastPackets)
410 }
411 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530412 return nnival
413}
414
415// collectPONMetrics will collect the pon port metrics
416func (StatMgr *OpenOltStatisticsMgr) collectPONMetrics(pID uint32) map[string]float32 {
Naga Manjunath7615e552019-10-11 22:35:47 +0530417 ponval := make(map[string]float32)
418 mutex.Lock()
419 cm := StatMgr.Device.portStats.SouthBoundPort[pID]
420 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000421 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530422
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000423 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400424 for metric := range metricNames {
425 if metricNames[metric].Enabled {
426 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530427 }
428 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000429
430 for _, mName := range metrics {
431 switch mName {
432 case "rx_bytes":
433 ponval["RxBytes"] = float32(cm.RxBytes)
434 case "rx_packets":
435 ponval["RxPackets"] = float32(cm.RxPackets)
436 case "rx_ucast_packets":
437 ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
438 case "rx_mcast_packets":
439 ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
440 case "rx_bcast_packets":
441 ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
442 case "tx_bytes":
443 ponval["TxBytes"] = float32(cm.TxBytes)
444 case "tx_packets":
445 ponval["TxPackets"] = float32(cm.TxPackets)
446 case "tx_mcast_packets":
447 ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
448 case "tx_bcast_packets":
449 ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
450 }
451 }
452
Naga Manjunath7615e552019-10-11 22:35:47 +0530453 return ponval
454}
455
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000456// converGemStats will convert gem stats response to kpi context
457func (StatMgr *OpenOltStatisticsMgr) convertGemStats(gemStats *openolt.GemPortStatistics) map[string]float32 {
458 gemStatsVal := make(map[string]float32)
459 gemStatsVal[IntfID] = float32(gemStats.IntfId)
460 gemStatsVal[GemID] = float32(gemStats.GemportId)
461 gemStatsVal[RxPackets] = float32(gemStats.RxPackets)
462 gemStatsVal[RxBytes] = float32(gemStats.RxBytes)
463 gemStatsVal[TxPackets] = float32(gemStats.TxPackets)
464 gemStatsVal[TxBytes] = float32(gemStats.TxBytes)
465 return gemStatsVal
466}
467
468// convertONUStats will convert onu stats response to kpi context
469func (StatMgr *OpenOltStatisticsMgr) convertONUStats(onuStats *openolt.OnuStatistics) map[string]float32 {
470 onuStatsVal := make(map[string]float32)
471 onuStatsVal[IntfID] = float32(onuStats.IntfId)
472 onuStatsVal[OnuID] = float32(onuStats.OnuId)
473 onuStatsVal[PositiveDrift] = float32(onuStats.PositiveDrift)
474 onuStatsVal[NegativeDrift] = float32(onuStats.NegativeDrift)
475 onuStatsVal[DelimiterMissDetection] = float32(onuStats.DelimiterMissDetection)
476 onuStatsVal[BipErrors] = float32(onuStats.BipErrors)
477 onuStatsVal[BipUnits] = float32(onuStats.BipUnits)
478 onuStatsVal[FecCorrectedSymbols] = float32(onuStats.FecCorrectedSymbols)
479 onuStatsVal[FecCodewordsCorrected] = float32(onuStats.FecCodewordsCorrected)
480 onuStatsVal[fecCodewordsUncorrectable] = float32(onuStats.FecCodewordsUncorrectable)
481 onuStatsVal[FecCodewords] = float32(onuStats.FecCodewords)
482 onuStatsVal[FecCorrectedUnits] = float32(onuStats.FecCorrectedUnits)
483 onuStatsVal[XGEMKeyErrors] = float32(onuStats.XgemKeyErrors)
484 onuStatsVal[XGEMLoss] = float32(onuStats.XgemLoss)
485 onuStatsVal[RxPloamsError] = float32(onuStats.RxPloamsError)
486 onuStatsVal[RxPloamsNonIdle] = float32(onuStats.RxPloamsNonIdle)
487 onuStatsVal[RxOmci] = float32(onuStats.RxOmci)
488 onuStatsVal[RxOmciPacketsCrcError] = float32(onuStats.RxOmciPacketsCrcError)
489 onuStatsVal[RxBytes] = float32(onuStats.RxBytes)
490 onuStatsVal[RxPackets] = float32(onuStats.RxPackets)
491 onuStatsVal[TxBytes] = float32(onuStats.TxBytes)
492 onuStatsVal[TxPackets] = float32(onuStats.TxPackets)
493 onuStatsVal[BerReported] = float32(onuStats.BerReported)
494 onuStatsVal[LcdgErrors] = float32(onuStats.LcdgErrors)
495 onuStatsVal[RdiErrors] = float32(onuStats.RdiErrors)
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530496 onuStatsVal[Timestamp] = float32(onuStats.Timestamp)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000497 return onuStatsVal
498}
499
500// collectOnuStats will collect the onu metrics
501func (StatMgr *OpenOltStatisticsMgr) collectOnuStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
502 onu := &openolt.Onu{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID}
503 logger.Debugw(ctx, "pulling-onu-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID})
504 if stats, err := StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
505 onuStats <- stats
506 } else {
507 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "err": err})
508 }
509}
510
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530511// collectOnDemandOnuStats will collect the onui-pon metrics
512func (StatMgr *OpenOltStatisticsMgr) collectOnDemandOnuStats(ctx context.Context, intfID uint32, onuID uint32) map[string]float32 {
513 onu := &openolt.Onu{IntfId: intfID, OnuId: onuID}
514 var stats *openolt.OnuStatistics
515 var err error
516 logger.Debugw(ctx, "pulling-onu-stats-on-demand", log.Fields{"IntfID": intfID, "OnuID": onuID})
517 if stats, err = StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
518 statValue := StatMgr.convertONUStats(stats)
519 return statValue
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530520 }
521 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": intfID, "OnuID": onuID, "err": err})
522 return nil
523}
524
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000525// collectOnuAndGemStats will collect both onu and gem metrics
526func (StatMgr *OpenOltStatisticsMgr) collectOnuAndGemStats(ctx context.Context, onuGemInfo []rsrcMgr.OnuGemInfo) {
527 if !StatMgr.Device.openOLT.enableONUStats && !StatMgr.Device.openOLT.enableGemStats {
528 return
529 }
530
531 for _, onuInfo := range onuGemInfo {
532 if StatMgr.Device.openOLT.enableONUStats {
533 go StatMgr.collectOnuStats(ctx, onuInfo)
534 }
535 if StatMgr.Device.openOLT.enableGemStats {
536 go StatMgr.collectGemStats(ctx, onuInfo)
537 }
538 }
539}
540
541// collectGemStats will collect gem metrics
542func (StatMgr *OpenOltStatisticsMgr) collectGemStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
543 for _, gem := range onuGemInfo.GemPorts {
544 logger.Debugw(ctx, "pulling-gem-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem})
545 onuPacket := &openolt.OnuPacket{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID, GemportId: gem}
546 if stats, err := StatMgr.Device.Client.GetGemPortStatistics(context.Background(), onuPacket); err == nil {
547 gemStats <- stats
548 } else {
549 logger.Errorw(ctx, "error-while-getting-gem-stats-for-onu",
550 log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem, "err": err})
551 }
552 }
553}
554
555// publishGemStats will publish the gem metrics
556func (StatMgr *OpenOltStatisticsMgr) publishGemStats() {
557 for {
558 statValue := StatMgr.convertGemStats(<-gemStats)
559 StatMgr.publishMetrics(context.Background(), GEMStats, statValue, &voltha.Port{Label: "GEM"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
560 }
561}
562
563// publishOnuStats will publish the onu metrics
564func (StatMgr *OpenOltStatisticsMgr) publishOnuStats() {
565 for {
566 statValue := StatMgr.convertONUStats(<-onuStats)
567 StatMgr.publishMetrics(context.Background(), ONUStats, statValue, &voltha.Port{Label: "ONU"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
568 }
569}
570
571// publishMetrics will publish the pon port metrics
kesavand62126212021-01-12 04:56:06 -0500572func (StatMgr *OpenOltStatisticsMgr) publishMetrics(ctx context.Context, statType string, val map[string]float32,
Girish Gowdra34815db2020-05-11 17:18:04 -0700573 port *voltha.Port, devID string, devType string) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000574 logger.Debugw(ctx, "publish-metrics",
Shrey Baid26912972020-04-16 21:02:31 +0530575 log.Fields{
576 "port": port.Label,
577 "metrics": val})
Naga Manjunath7615e552019-10-11 22:35:47 +0530578
579 var metricInfo voltha.MetricInformation
580 var ke voltha.KpiEvent2
Esin Karamanccb714b2019-11-29 15:02:06 +0000581 var volthaEventSubCatgry voltha.EventSubCategory_Types
Girish Gowdra34815db2020-05-11 17:18:04 -0700582 metricsContext := make(map[string]string)
583 metricsContext["oltid"] = devID
584 metricsContext["devicetype"] = devType
585 metricsContext["portlabel"] = port.Label
Naga Manjunath7615e552019-10-11 22:35:47 +0530586
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000587 if statType == NNIStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530588 volthaEventSubCatgry = voltha.EventSubCategory_NNI
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000589 } else if statType == PONStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530590 volthaEventSubCatgry = voltha.EventSubCategory_PON
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000591 } else if statType == GEMStats || statType == ONUStats {
592 volthaEventSubCatgry = voltha.EventSubCategory_ONT
Naga Manjunath7615e552019-10-11 22:35:47 +0530593 }
594
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700595 raisedTs := time.Now().Unix()
Naga Manjunath7615e552019-10-11 22:35:47 +0530596 mmd := voltha.MetricMetaData{
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000597 Title: statType,
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700598 Ts: float64(raisedTs),
Girish Gowdra34815db2020-05-11 17:18:04 -0700599 Context: metricsContext,
Naga Manjunath7615e552019-10-11 22:35:47 +0530600 DeviceId: devID,
601 }
602
603 metricInfo.Metadata = &mmd
604 metricInfo.Metrics = val
605
606 ke.SliceData = []*voltha.MetricInformation{&metricInfo}
607 ke.Type = voltha.KpiEventType_slice
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700608 ke.Ts = float64(raisedTs)
Naga Manjunath7615e552019-10-11 22:35:47 +0530609
Himani Chawla473496d2021-12-01 00:10:30 +0530610 if err := StatMgr.Device.EventProxy.SendKpiEvent(ctx, "STATS_PUBLISH_EVENT", &ke, voltha.EventCategory_EQUIPMENT, volthaEventSubCatgry, raisedTs); err != nil {
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000611 logger.Errorw(ctx, "failed-to-send-stats", log.Fields{"err": err})
Naga Manjunath7615e552019-10-11 22:35:47 +0530612 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530613}
614
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615// PortStatisticsIndication handles the port statistics indication
Akash Reddy Kankanalac6b6ca12025-06-12 14:26:57 +0530616func (StatMgr *OpenOltStatisticsMgr) PortStatisticsIndication(ctx context.Context, PortStats *common.PortStatistics, NumPonPorts uint32) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000617 StatMgr.PortsStatisticsKpis(ctx, PortStats, NumPonPorts)
618 logger.Debugw(ctx, "received-port-stats-indication", log.Fields{"port-stats": PortStats})
Akash Kankanala041a2122024-10-16 15:49:22 +0530619 // Indicate that PortStatisticsIndication is handled
620 // PortStats.IntfId is actually the port number
kesavand62126212021-01-12 04:56:06 -0500621 StatMgr.processStatIndication(ctx, portStatsType, PortStats.IntfId)
Abhilash S.L765ad002019-04-24 16:40:57 +0530622 // TODO send stats to core topic to the voltha kafka or a different kafka ?
623}
624
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625// FlowStatisticsIndication to be implemented
Neha Sharma96b7bf22020-06-15 10:37:32 +0000626func FlowStatisticsIndication(ctx context.Context, self, FlowStats *openolt.FlowStatistics) {
627 logger.Debugw(ctx, "flow-stats-collected", log.Fields{"flow-stats": FlowStats})
Akash Kankanala041a2122024-10-16 15:49:22 +0530628 // TODO send to kafka ?
Abhilash S.L765ad002019-04-24 16:40:57 +0530629}
630
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700631// PortsStatisticsKpis map the port stats values into a dictionary, creates the kpiEvent and then publish to Kafka
Akash Reddy Kankanalac6b6ca12025-06-12 14:26:57 +0530632func (StatMgr *OpenOltStatisticsMgr) PortsStatisticsKpis(ctx context.Context, PortStats *common.PortStatistics, NumPonPorts uint32) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530633 /*map the port stats values into a dictionary
634 Create a kpoEvent and publish to Kafka
635
636 :param port_stats:
637 :return:
638 */
Akash Kankanala041a2122024-10-16 15:49:22 +0530639 // var err error
Abhilash S.L765ad002019-04-24 16:40:57 +0530640 IntfID := PortStats.IntfId
641
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700642 if (plt.IntfIDToPortNo(1, voltha.Port_ETHERNET_NNI) < IntfID) &&
643 (IntfID < plt.IntfIDToPortNo(4, voltha.Port_ETHERNET_NNI)) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530644 /*
645 for this release we are only interested in the first NNI for
646 Northbound.
647 we are not using the other 3
648 */
649 return
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700650 } else if plt.IntfIDToPortNo(0, voltha.Port_ETHERNET_NNI) == IntfID {
Naga Manjunath7615e552019-10-11 22:35:47 +0530651 var portNNIStat NniPort
652 portNNIStat.IntfID = IntfID
653 portNNIStat.PortNum = uint32(0)
654 portNNIStat.RxBytes = PortStats.RxBytes
655 portNNIStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000656 portNNIStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530657 portNNIStat.RxMcastPackets = PortStats.RxMcastPackets
658 portNNIStat.RxBcastPackets = PortStats.RxBcastPackets
659 portNNIStat.TxBytes = PortStats.TxBytes
660 portNNIStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000661 portNNIStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530662 portNNIStat.TxMcastPackets = PortStats.TxMcastPackets
663 portNNIStat.TxBcastPackets = PortStats.TxBcastPackets
664 mutex.Lock()
665 StatMgr.NorthBoundPort[0] = &portNNIStat
666 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000667 logger.Debugw(ctx, "received-nni-stats", log.Fields{"nni-stats": StatMgr.NorthBoundPort})
Naga Manjunath7615e552019-10-11 22:35:47 +0530668 }
669 for i := uint32(0); i < NumPonPorts; i++ {
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700670 if plt.IntfIDToPortNo(i, voltha.Port_PON_OLT) == IntfID {
Naga Manjunath7615e552019-10-11 22:35:47 +0530671 var portPonStat PonPort
672 portPonStat.IntfID = IntfID
673 portPonStat.PortNum = i
674 portPonStat.PONID = i
675 portPonStat.RxBytes = PortStats.RxBytes
676 portPonStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000677 portPonStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530678 portPonStat.RxMcastPackets = PortStats.RxMcastPackets
679 portPonStat.RxBcastPackets = PortStats.RxBcastPackets
680 portPonStat.TxBytes = PortStats.TxBytes
681 portPonStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000682 portPonStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530683 portPonStat.TxMcastPackets = PortStats.TxMcastPackets
684 portPonStat.TxBcastPackets = PortStats.TxBcastPackets
685 mutex.Lock()
686 StatMgr.SouthBoundPort[i] = &portPonStat
687 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000688 logger.Debugw(ctx, "received-pon-stats-for-port", log.Fields{"port-pon-stats": portPonStat})
Naga Manjunath7615e552019-10-11 22:35:47 +0530689 }
690 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700691 /*
692 Based upon the intf_id map to an nni port or a pon port
693 the intf_id is the key to the north or south bound collections
694
695 Based upon the intf_id the port object (nni_port or pon_port) will
696 have its data attr. updated by the current dataset collected.
697
698 For prefixing the rule is currently to use the port number and not the intf_id
699 */
Akash Kankanala041a2122024-10-16 15:49:22 +0530700 // FIXME : Just use first NNI for now
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700701 /* TODO should the data be marshaled before sending it ?
702 if IntfID == IntfIdToPortNo(0, voltha.Port_ETHERNET_NNI) {
703 //NNI port (just the first one)
704 err = UpdatePortObjectKpiData(StatMgr.NorthBoundPorts[PortStats.IntfID], PMData)
705 } else {
706 //PON ports
707 err = UpdatePortObjectKpiData(SouthboundPorts[PortStats.IntfID], PMData)
708 }
709 if (err != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000710 logger.Error(ctx, "Error publishing statistics data")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700711 }
712 */
Abhilash S.L765ad002019-04-24 16:40:57 +0530713}
kesavand62126212021-01-12 04:56:06 -0500714
715func (StatMgr *OpenOltStatisticsMgr) updateGetOltPortCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
kesavand62126212021-01-12 04:56:06 -0500716 metrics := singleValResp.GetResponse().GetPortCoutners()
717 metrics.TxBytes = uint64(stats["TxBytes"])
718 metrics.RxBytes = uint64(stats["RxBytes"])
719 metrics.TxPackets = uint64(stats["TxPackets"])
720 metrics.RxPackets = uint64(stats["RxPackets"])
721 metrics.TxErrorPackets = uint64(stats["TxErrorPackets"])
722 metrics.RxErrorPackets = uint64(stats["RxErrorPackets"])
723 metrics.TxBcastPackets = uint64(stats["TxBcastPackets"])
724 metrics.RxBcastPackets = uint64(stats["RxBcastPackets"])
725 metrics.TxUcastPackets = uint64(stats["TxUcastPackets"])
726 metrics.RxUcastPackets = uint64(stats["RxUcastPackets"])
727 metrics.TxMcastPackets = uint64(stats["TxMcastPackets"])
728 metrics.RxMcastPackets = uint64(stats["RxMcastPackets"])
729
730 singleValResp.Response.Status = extension.GetValueResponse_OK
731 logger.Debugw(ctx, "updateGetOltPortCountersResponse", log.Fields{"resp": singleValResp})
732}
733
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400734// RegisterForStatIndication registers ch as a channel on which indication is sent when statistics of type t is received
kesavand62126212021-01-12 04:56:06 -0500735func (StatMgr *OpenOltStatisticsMgr) RegisterForStatIndication(ctx context.Context, t StatType, ch chan bool, portNo uint32, portType extension.GetOltPortCounters_PortType) {
736 statInd := statRegInfo{
737 chn: ch,
738 portNo: portNo,
739 portType: portType,
740 }
741
742 logger.Debugf(ctx, "RegisterForStatIndication stat type %v portno %v porttype %v chan %v", t, portNo, portType, ch)
743 StatMgr.statIndListnerMu.Lock()
744 StatMgr.statIndListners[t].PushBack(statInd)
745 StatMgr.statIndListnerMu.Unlock()
kesavand62126212021-01-12 04:56:06 -0500746}
747
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400748// DeRegisterFromStatIndication removes the previously registered channel ch for type t of statistics
kesavand62126212021-01-12 04:56:06 -0500749func (StatMgr *OpenOltStatisticsMgr) DeRegisterFromStatIndication(ctx context.Context, t StatType, ch chan bool) {
750 StatMgr.statIndListnerMu.Lock()
751 defer StatMgr.statIndListnerMu.Unlock()
752
753 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
754 statInd := e.Value.(statRegInfo)
755 if statInd.chn == ch {
756 StatMgr.statIndListners[t].Remove(e)
757 return
758 }
759 }
760}
761
762func (StatMgr *OpenOltStatisticsMgr) processStatIndication(ctx context.Context, t StatType, portNo uint32) {
763 var deRegList []*list.Element
764 var statInd statRegInfo
765
766 StatMgr.statIndListnerMu.Lock()
767 defer StatMgr.statIndListnerMu.Unlock()
768
769 if StatMgr.statIndListners[t] == nil || StatMgr.statIndListners[t].Len() == 0 {
770 logger.Debugf(ctx, "processStatIndication %v list is empty ", t)
771 return
772 }
773
774 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
775 statInd = e.Value.(statRegInfo)
776 if statInd.portNo != portNo {
777 fmt.Printf("Skipping %v\n", e.Value)
778 continue
779 }
780 // message sent
781 statInd.chn <- true
782 deRegList = append(deRegList, e)
kesavand62126212021-01-12 04:56:06 -0500783 }
784 for _, e := range deRegList {
785 StatMgr.statIndListners[t].Remove(e)
786 }
kesavand62126212021-01-12 04:56:06 -0500787}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530788
789func (StatMgr *OpenOltStatisticsMgr) updateGetOnuPonCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530790 metrics := singleValResp.GetResponse().GetOnuPonCounters()
791 metrics.IsIntfId = &extension.GetOnuCountersResponse_IntfId{
792 IntfId: uint32(stats[IntfID]),
793 }
794 metrics.IsOnuId = &extension.GetOnuCountersResponse_OnuId{
795 OnuId: uint32(stats[OnuID]),
796 }
797 metrics.IsPositiveDrift = &extension.GetOnuCountersResponse_PositiveDrift{
798 PositiveDrift: uint64(stats[PositiveDrift]),
799 }
800 metrics.IsNegativeDrift = &extension.GetOnuCountersResponse_NegativeDrift{
801 NegativeDrift: uint64(stats[NegativeDrift]),
802 }
803 metrics.IsDelimiterMissDetection = &extension.GetOnuCountersResponse_DelimiterMissDetection{
804 DelimiterMissDetection: uint64(stats[DelimiterMissDetection]),
805 }
806 metrics.IsBipErrors = &extension.GetOnuCountersResponse_BipErrors{
807 BipErrors: uint64(stats[BipErrors]),
808 }
809 metrics.IsBipUnits = &extension.GetOnuCountersResponse_BipUnits{
810 BipUnits: uint64(stats[BipUnits]),
811 }
812 metrics.IsFecCorrectedSymbols = &extension.GetOnuCountersResponse_FecCorrectedSymbols{
813 FecCorrectedSymbols: uint64(stats[FecCorrectedSymbols]),
814 }
815 metrics.IsFecCodewordsCorrected = &extension.GetOnuCountersResponse_FecCodewordsCorrected{
816 FecCodewordsCorrected: uint64(stats[FecCodewordsCorrected]),
817 }
818 metrics.IsFecCodewordsUncorrectable = &extension.GetOnuCountersResponse_FecCodewordsUncorrectable{
819 FecCodewordsUncorrectable: uint64(stats[fecCodewordsUncorrectable]),
820 }
821 metrics.IsFecCodewords = &extension.GetOnuCountersResponse_FecCodewords{
822 FecCodewords: uint64(stats[FecCodewords]),
823 }
824 metrics.IsFecCorrectedUnits = &extension.GetOnuCountersResponse_FecCorrectedUnits{
825 FecCorrectedUnits: uint64(stats[FecCorrectedUnits]),
826 }
827 metrics.IsXgemKeyErrors = &extension.GetOnuCountersResponse_XgemKeyErrors{
828 XgemKeyErrors: uint64(stats[XGEMKeyErrors]),
829 }
830 metrics.IsXgemLoss = &extension.GetOnuCountersResponse_XgemLoss{
831 XgemLoss: uint64(stats[XGEMLoss]),
832 }
833 metrics.IsRxPloamsError = &extension.GetOnuCountersResponse_RxPloamsError{
834 RxPloamsError: uint64(stats[RxPloamsError]),
835 }
836 metrics.IsRxPloamsNonIdle = &extension.GetOnuCountersResponse_RxPloamsNonIdle{
837 RxPloamsNonIdle: uint64(stats[RxPloamsNonIdle]),
838 }
839 metrics.IsRxOmci = &extension.GetOnuCountersResponse_RxOmci{
840 RxOmci: uint64(stats[RxOmci]),
841 }
842 metrics.IsRxOmciPacketsCrcError = &extension.GetOnuCountersResponse_RxOmciPacketsCrcError{
843 RxOmciPacketsCrcError: uint64(stats[RxOmciPacketsCrcError]),
844 }
845 metrics.IsRxBytes = &extension.GetOnuCountersResponse_RxBytes{
846 RxBytes: uint64(stats[RxBytes]),
847 }
848 metrics.IsRxPackets = &extension.GetOnuCountersResponse_RxPackets{
849 RxPackets: uint64(stats[RxPackets]),
850 }
851 metrics.IsTxBytes = &extension.GetOnuCountersResponse_TxBytes{
852 TxBytes: uint64(stats[TxBytes]),
853 }
854 metrics.IsTxPackets = &extension.GetOnuCountersResponse_TxPackets{
855 TxPackets: uint64(stats[TxPackets]),
856 }
857 metrics.IsBerReported = &extension.GetOnuCountersResponse_BerReported{
858 BerReported: uint64(stats[BerReported]),
859 }
860 metrics.IsLcdgErrors = &extension.GetOnuCountersResponse_LcdgErrors{
861 LcdgErrors: uint64(stats[LcdgErrors]),
862 }
863 metrics.IsRdiErrors = &extension.GetOnuCountersResponse_RdiErrors{
864 RdiErrors: uint64(stats[RdiErrors]),
865 }
866 metrics.IsTimestamp = &extension.GetOnuCountersResponse_Timestamp{
867 Timestamp: uint32(stats[Timestamp]),
868 }
869
870 singleValResp.Response.Status = extension.GetValueResponse_OK
871 logger.Debugw(ctx, "updateGetOnuPonCountersResponse", log.Fields{"resp": singleValResp})
872}