blob: 1f9d7f902372ff9892cc09f9f8135a322759d25f [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"
khenaidoo106c61a2021-08-11 18:05:46 -040032 "github.com/opencord/voltha-protos/v5/go/extension"
33 "github.com/opencord/voltha-protos/v5/go/openolt"
34 "github.com/opencord/voltha-protos/v5/go/voltha"
Abhilash S.L765ad002019-04-24 16:40:57 +053035)
36
Gamze Abakafcbd6e72020-12-17 13:25:16 +000037const (
Akash Kankanala041a2122024-10-16 15:49:22 +053038 // NNIStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000039 NNIStats = "NNIStats"
Akash Kankanala041a2122024-10-16 15:49:22 +053040 // PONStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000041 PONStats = "PONStats"
Akash Kankanala041a2122024-10-16 15:49:22 +053042 // ONUStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000043 ONUStats = "ONUStats"
Akash Kankanala041a2122024-10-16 15:49:22 +053044 // GEMStats statType constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000045 GEMStats = "GEMStats"
46
Akash Kankanala041a2122024-10-16 15:49:22 +053047 // RxBytes constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000048 RxBytes = "RxBytes"
Akash Kankanala041a2122024-10-16 15:49:22 +053049 // RxPackets constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000050 RxPackets = "RxPackets"
Akash Kankanala041a2122024-10-16 15:49:22 +053051 // TxBytes constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000052 TxBytes = "TxBytes"
Akash Kankanala041a2122024-10-16 15:49:22 +053053 // TxPackets constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000054 TxPackets = "TxPackets"
Akash Kankanala041a2122024-10-16 15:49:22 +053055 // FecCodewords constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000056 FecCodewords = "FecCodewords"
Akash Kankanala041a2122024-10-16 15:49:22 +053057 // BipUnits constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000058 BipUnits = "BipUnits"
Akash Kankanala041a2122024-10-16 15:49:22 +053059 // BipErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000060 BipErrors = "BipErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053061 // RxPloamsNonIdle constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000062 RxPloamsNonIdle = "RxPloamsNonIdle"
Akash Kankanala041a2122024-10-16 15:49:22 +053063 // RxPloamsError constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000064 RxPloamsError = "RxPloamsError"
Akash Kankanala041a2122024-10-16 15:49:22 +053065 // RxOmci constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000066 RxOmci = "RxOmci"
Akash Kankanala041a2122024-10-16 15:49:22 +053067 // RxOmciPacketsCrcError constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000068 RxOmciPacketsCrcError = "RxOmciPacketsCrcError"
Akash Kankanala041a2122024-10-16 15:49:22 +053069 // PositiveDrift constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000070 PositiveDrift = "PositiveDrift"
Akash Kankanala041a2122024-10-16 15:49:22 +053071 // NegativeDrift constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000072 NegativeDrift = "NegativeDrift"
Akash Kankanala041a2122024-10-16 15:49:22 +053073 // DelimiterMissDetection constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000074 DelimiterMissDetection = "DelimiterMissDetection"
Akash Kankanala041a2122024-10-16 15:49:22 +053075 // FecCorrectedSymbols constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000076 FecCorrectedSymbols = "FecCorrectedSymbols"
Akash Kankanala041a2122024-10-16 15:49:22 +053077 // FecCodewordsCorrected constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000078 FecCodewordsCorrected = "FecCodewordsCorrected"
Akash Kankanala041a2122024-10-16 15:49:22 +053079 // fecCodewordsUncorrectable constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000080 fecCodewordsUncorrectable = "fec_codewords_uncorrectable"
Akash Kankanala041a2122024-10-16 15:49:22 +053081 // FecCorrectedUnits constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000082 FecCorrectedUnits = "FecCorrectedUnits"
Akash Kankanala041a2122024-10-16 15:49:22 +053083 // XGEMKeyErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000084 XGEMKeyErrors = "XGEMKeyErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053085 // XGEMLoss constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000086 XGEMLoss = "XGEMLOSS"
Akash Kankanala041a2122024-10-16 15:49:22 +053087 // BerReported constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000088 BerReported = "BerReported"
Akash Kankanala041a2122024-10-16 15:49:22 +053089 // LcdgErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000090 LcdgErrors = "LcdgErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053091 // RdiErrors constant
Gamze Abakafcbd6e72020-12-17 13:25:16 +000092 RdiErrors = "RdiErrors"
Akash Kankanala041a2122024-10-16 15:49:22 +053093 // Timestamp constant
Himani Chawla2c8ae0f2021-05-18 23:27:00 +053094 Timestamp = "Timestamp"
Gamze Abakafcbd6e72020-12-17 13:25:16 +000095)
96
Naga Manjunath7615e552019-10-11 22:35:47 +053097var mutex = &sync.Mutex{}
98
Gamze Abakafcbd6e72020-12-17 13:25:16 +000099var onuStats = make(chan *openolt.OnuStatistics, 100)
100var gemStats = make(chan *openolt.GemPortStatistics, 100)
101
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400102// statRegInfo is used to register for notifications
103// on receiving port stats and flow stats indication
kesavand62126212021-01-12 04:56:06 -0500104type statRegInfo struct {
105 chn chan bool
106 portNo uint32
107 portType extension.GetOltPortCounters_PortType
108}
109
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110// PonPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530111type PonPort struct {
Abhilash S.L765ad002019-04-24 16:40:57 +0530112 ONUs map[uint32]interface{}
113 ONUsByID map[uint32]interface{}
114
Akash Kankanala041a2122024-10-16 15:49:22 +0530115 DeviceID string
116 Label string
117
Abhilash S.L765ad002019-04-24 16:40:57 +0530118 RxBytes uint64
119 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000120 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530121 RxMcastPackets uint64
122 RxBcastPackets uint64
123 RxErrorPackets uint64
124 TxBytes uint64
125 TxPackets uint64
126 TxUcastPackets uint64
127 TxMcastPackets uint64
128 TxBcastPackets uint64
129 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000130 RxCrcErrors uint64
131 BipErrors uint64
Akash Kankanala041a2122024-10-16 15:49:22 +0530132 /*
133 This is a highly reduced version taken from the adtran pon_port.
134 TODO: Extend for use in the openolt adapter set.
135 */
136 /* MAX_ONUS_SUPPORTED = 256
137 DEFAULT_ENABLED = False
138 MAX_DEPLOYMENT_RANGE = 25000 # Meters (OLT-PB maximum)
139
140 _MCAST_ONU_ID = 253
141 _MCAST_ALLOC_BASE = 0x500
142
143 _SUPPORTED_ACTIVATION_METHODS = ['autodiscovery'] # , 'autoactivate']
144 _SUPPORTED_AUTHENTICATION_METHODS = ['serial-number']
145 */
146 PONID uint32
147 IntfID uint32
148 PortNum uint32
149 PortID uint32
Abhilash S.L765ad002019-04-24 16:40:57 +0530150}
151
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700152// NewPONPort returns a new instance of PonPort initialized with given PONID, DeviceID, IntfID and PortNum
Abhilash S.L765ad002019-04-24 16:40:57 +0530153func NewPONPort(PONID uint32, DeviceID string, IntfID uint32, PortNum uint32) *PonPort {
Abhilash S.L765ad002019-04-24 16:40:57 +0530154 var PON PonPort
155
156 PON.PONID = PONID
157 PON.DeviceID = DeviceID
158 PON.IntfID = IntfID
159 PON.PortNum = PortNum
160 PON.PortID = 0
Naga Manjunath7615e552019-10-11 22:35:47 +0530161 PON.Label = fmt.Sprintf("%s%d", "pon-", PONID)
Abhilash S.L765ad002019-04-24 16:40:57 +0530162
163 PON.ONUs = make(map[uint32]interface{})
164 PON.ONUsByID = make(map[uint32]interface{})
165
166 /*
167 Statistics taken from nni_port
168 self.intf_id = 0 #handled by getter
169 self.port_no = 0 #handled by getter
170 self.port_id = 0 #handled by getter
171
172 Note: In the current implementation of the kpis coming from the BAL the stats are the
173 samne model for NNI and PON.
174
175 TODO: Integrate additional kpis for the PON and other southbound port objecgts.
176
177 */
178
179 PON.RxBytes = 0
180 PON.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000181 PON.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530182 PON.RxMcastPackets = 0
183 PON.RxBcastPackets = 0
184 PON.RxErrorPackets = 0
185 PON.TxBytes = 0
186 PON.TxPackets = 0
187 PON.TxUcastPackets = 0
188 PON.TxMcastPackets = 0
189 PON.TxBcastPackets = 0
190 PON.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000191 PON.RxCrcErrors = 0
192 PON.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530193
194 /* def __str__(self):
195 return "PonPort-{}: Admin: {}, Oper: {}, OLT: {}".format(self._label,
196 self._admin_state,
197 self._oper_status,
198 self.olt)
199 */
200 return &PON
201}
202
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700203// NniPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530204type NniPort struct {
Akash Kankanala041a2122024-10-16 15:49:22 +0530205 Name string
Abhilash S.L765ad002019-04-24 16:40:57 +0530206
207 RxBytes uint64
208 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000209 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530210 RxMcastPackets uint64
211 RxBcastPackets uint64
212 RxErrorPackets uint64
213 TxBytes uint64
214 TxPackets uint64
215 TxUcastPackets uint64
216 TxMcastPackets uint64
217 TxBcastPackets uint64
218 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000219 RxCrcErrors uint64
220 BipErrors uint64
Akash Kankanala041a2122024-10-16 15:49:22 +0530221 /*
222 Northbound network port, often Ethernet-based
223
224 This is a highly reduced version taken from the adtran nni_port code set
225 TODO: add functions to allow for port specific values and operations
226 */
227 PortNum uint32
228 LogicalPort uint32
229 IntfID uint32
Abhilash S.L765ad002019-04-24 16:40:57 +0530230}
231
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700232// NewNniPort returns a new instance of NniPort initialized with the given PortNum and IntfID
Abhilash S.L765ad002019-04-24 16:40:57 +0530233func NewNniPort(PortNum uint32, IntfID uint32) *NniPort {
Abhilash S.L765ad002019-04-24 16:40:57 +0530234 var NNI NniPort
235
236 NNI.PortNum = PortNum
Naga Manjunath7615e552019-10-11 22:35:47 +0530237 NNI.Name = fmt.Sprintf("%s%d", "nni-", PortNum)
Abhilash S.L765ad002019-04-24 16:40:57 +0530238 NNI.IntfID = IntfID
239
240 NNI.RxBytes = 0
241 NNI.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000242 NNI.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530243 NNI.RxMcastPackets = 0
244 NNI.RxBcastPackets = 0
245 NNI.RxErrorPackets = 0
246 NNI.TxBytes = 0
247 NNI.TxPackets = 0
248 NNI.TxUcastPackets = 0
249 NNI.TxMcastPackets = 0
250 NNI.TxBcastPackets = 0
251 NNI.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000252 NNI.RxCrcErrors = 0
253 NNI.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530254
255 return &NNI
256}
257
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400258// StatType defines portStatsType and flowStatsType types
kesavand62126212021-01-12 04:56:06 -0500259type StatType int
260
261const (
262 portStatsType StatType = iota
263 flowStatsType
264)
265
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700266// OpenOltStatisticsMgr structure
Abhilash S.L765ad002019-04-24 16:40:57 +0530267type OpenOltStatisticsMgr struct {
Akash Kankanala041a2122024-10-16 15:49:22 +0530268 Device *DeviceHandler
269 NorthBoundPort map[uint32]*NniPort
270 SouthBoundPort map[uint32]*PonPort
271 statIndListners map[StatType]*list.List
Abhilash S.L765ad002019-04-24 16:40:57 +0530272 // TODO PMMetrics Metrics
Akash Kankanala041a2122024-10-16 15:49:22 +0530273 // statIndListners is the list of requests to be notified when port and flow stats indication is received
kesavand62126212021-01-12 04:56:06 -0500274 statIndListnerMu sync.Mutex
Abhilash S.L765ad002019-04-24 16:40:57 +0530275}
276
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700277// NewOpenOltStatsMgr returns a new instance of the OpenOltStatisticsMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000278func NewOpenOltStatsMgr(ctx context.Context, Dev *DeviceHandler) *OpenOltStatisticsMgr {
Abhilash S.L765ad002019-04-24 16:40:57 +0530279 var StatMgr OpenOltStatisticsMgr
280
281 StatMgr.Device = Dev
282 // TODO call metric PMMetric =
283 // Northbound and Southbound ports
284 // added to initialize the pm_metrics
285 var Ports interface{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000286 Ports, _ = InitPorts(ctx, "nni", Dev.device.Id, 1)
Naga Manjunath7615e552019-10-11 22:35:47 +0530287 StatMgr.NorthBoundPort, _ = Ports.(map[uint32]*NniPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700288 NumPonPorts := Dev.resourceMgr[0].DevInfo.GetPonPorts()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000289 Ports, _ = InitPorts(ctx, "pon", Dev.device.Id, NumPonPorts)
Naga Manjunath7615e552019-10-11 22:35:47 +0530290 StatMgr.SouthBoundPort, _ = Ports.(map[uint32]*PonPort)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000291 if StatMgr.Device.openOLT.enableONUStats {
292 go StatMgr.publishOnuStats()
293 }
294 if StatMgr.Device.openOLT.enableGemStats {
295 go StatMgr.publishGemStats()
296 }
kesavand62126212021-01-12 04:56:06 -0500297 StatMgr.statIndListners = make(map[StatType]*list.List)
298 StatMgr.statIndListners[portStatsType] = list.New()
299 StatMgr.statIndListners[flowStatsType] = list.New()
Abhilash S.L765ad002019-04-24 16:40:57 +0530300 return &StatMgr
301}
302
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700303// 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 +0000304func InitPorts(ctx context.Context, Intftype string, DeviceID string, numOfPorts uint32) (interface{}, error) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530305 /*
306 This method collects the port objects: nni and pon that are updated with the
307 current data from the OLT
308
309 Both the northbound (nni) and southbound ports are indexed by the interface id (intf_id)
310 and NOT the port number. When the port object is instantiated it will contain the intf_id and
311 port_no values
312
313 :param type:
314 :return:
315 */
316 var i uint32
317 if Intftype == "nni" {
Naga Manjunath7615e552019-10-11 22:35:47 +0530318 NniPorts := make(map[uint32]*NniPort)
319 for i = 0; i < numOfPorts; i++ {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000320 Port := BuildPortObject(ctx, i, "nni", DeviceID).(*NniPort)
Naga Manjunath7615e552019-10-11 22:35:47 +0530321 NniPorts[Port.IntfID] = Port
Abhilash S.L765ad002019-04-24 16:40:57 +0530322 }
323 return NniPorts, nil
324 } else if Intftype == "pon" {
Naga Manjunath7615e552019-10-11 22:35:47 +0530325 PONPorts := make(map[uint32]*PonPort)
326 for i = 0; i < numOfPorts; i++ {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000327 PONPort := BuildPortObject(ctx, i, "pon", DeviceID).(*PonPort)
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700328 PONPorts[plt.PortNoToIntfID(PONPort.IntfID, voltha.Port_PON_OLT)] = PONPort
Abhilash S.L765ad002019-04-24 16:40:57 +0530329 }
330 return PONPorts, nil
331 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000332 logger.Errorw(ctx, "invalid-type-of-interface", log.Fields{"interface-type": Intftype})
Thomas Lee S94109f12020-03-03 16:39:29 +0530333 return nil, olterrors.NewErrInvalidValue(log.Fields{"interface-type": Intftype}, nil)
Abhilash S.L765ad002019-04-24 16:40:57 +0530334 }
335}
336
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700337// BuildPortObject allows for updating north and southbound ports, newly discovered ports, and devices
Neha Sharma96b7bf22020-06-15 10:37:32 +0000338func BuildPortObject(ctx context.Context, PortNum uint32, IntfType string, DeviceID string) interface{} {
Abhilash S.L765ad002019-04-24 16:40:57 +0530339 /*
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700340 Separate method to allow for updating north and southbound ports
Abhilash S.L765ad002019-04-24 16:40:57 +0530341 newly discovered ports and devices
342
343 :param port_num:
344 :param type:
345 :return:
346 */
347
Akash Kankanala041a2122024-10-16 15:49:22 +0530348 // This builds a port object which is added to the
349 // appropriate northbound or southbound values
Abhilash S.L765ad002019-04-24 16:40:57 +0530350 if IntfType == "nni" {
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700351 IntfID := plt.IntfIDToPortNo(PortNum, voltha.Port_ETHERNET_NNI)
352 nniID := plt.PortNoToIntfID(IntfID, voltha.Port_ETHERNET_NNI)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000353 logger.Debugw(ctx, "interface-type-nni",
Shrey Baid26912972020-04-16 21:02:31 +0530354 log.Fields{
355 "nni-id": nniID,
356 "intf-type": IntfType})
Naga Manjunath7615e552019-10-11 22:35:47 +0530357 return NewNniPort(PortNum, nniID)
Abhilash S.L765ad002019-04-24 16:40:57 +0530358 } else if IntfType == "pon" {
359 // PON ports require a different configuration
360 // intf_id and pon_id are currently equal.
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700361 IntfID := plt.IntfIDToPortNo(PortNum, voltha.Port_PON_OLT)
362 PONID := plt.PortNoToIntfID(IntfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000363 logger.Debugw(ctx, "interface-type-pon",
Shrey Baid26912972020-04-16 21:02:31 +0530364 log.Fields{
365 "pon-id": PONID,
366 "intf-type": IntfType})
Abhilash S.L765ad002019-04-24 16:40:57 +0530367 return NewPONPort(PONID, DeviceID, IntfID, PortNum)
368 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000369 logger.Errorw(ctx, "invalid-type-of-interface", log.Fields{"intf-type": IntfType})
Abhilash S.L765ad002019-04-24 16:40:57 +0530370 return nil
371 }
372}
373
Naga Manjunath7615e552019-10-11 22:35:47 +0530374// collectNNIMetrics will collect the nni port metrics
375func (StatMgr *OpenOltStatisticsMgr) collectNNIMetrics(nniID uint32) map[string]float32 {
Naga Manjunath7615e552019-10-11 22:35:47 +0530376 nnival := make(map[string]float32)
377 mutex.Lock()
378 cm := StatMgr.Device.portStats.NorthBoundPort[nniID]
379 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000380 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530381
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000382 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400383 for metric := range metricNames {
384 if metricNames[metric].Enabled {
385 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530386 }
387 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000388
389 for _, mName := range metrics {
390 switch mName {
391 case "rx_bytes":
392 nnival["RxBytes"] = float32(cm.RxBytes)
393 case "rx_packets":
394 nnival["RxPackets"] = float32(cm.RxPackets)
395 case "rx_ucast_packets":
396 nnival["RxUcastPackets"] = float32(cm.RxUcastPackets)
397 case "rx_mcast_packets":
398 nnival["RxMcastPackets"] = float32(cm.RxMcastPackets)
399 case "rx_bcast_packets":
400 nnival["RxBcastPackets"] = float32(cm.RxBcastPackets)
401 case "tx_bytes":
402 nnival["TxBytes"] = float32(cm.TxBytes)
403 case "tx_packets":
404 nnival["TxPackets"] = float32(cm.TxPackets)
405 case "tx_mcast_packets":
406 nnival["TxMcastPackets"] = float32(cm.TxMcastPackets)
407 case "tx_bcast_packets":
408 nnival["TxBcastPackets"] = float32(cm.TxBcastPackets)
409 }
410 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530411 return nnival
412}
413
414// collectPONMetrics will collect the pon port metrics
415func (StatMgr *OpenOltStatisticsMgr) collectPONMetrics(pID uint32) map[string]float32 {
Naga Manjunath7615e552019-10-11 22:35:47 +0530416 ponval := make(map[string]float32)
417 mutex.Lock()
418 cm := StatMgr.Device.portStats.SouthBoundPort[pID]
419 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000420 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530421
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000422 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400423 for metric := range metricNames {
424 if metricNames[metric].Enabled {
425 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530426 }
427 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000428
429 for _, mName := range metrics {
430 switch mName {
431 case "rx_bytes":
432 ponval["RxBytes"] = float32(cm.RxBytes)
433 case "rx_packets":
434 ponval["RxPackets"] = float32(cm.RxPackets)
435 case "rx_ucast_packets":
436 ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
437 case "rx_mcast_packets":
438 ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
439 case "rx_bcast_packets":
440 ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
441 case "tx_bytes":
442 ponval["TxBytes"] = float32(cm.TxBytes)
443 case "tx_packets":
444 ponval["TxPackets"] = float32(cm.TxPackets)
445 case "tx_mcast_packets":
446 ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
447 case "tx_bcast_packets":
448 ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
449 }
450 }
451
Naga Manjunath7615e552019-10-11 22:35:47 +0530452 return ponval
453}
454
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000455// converGemStats will convert gem stats response to kpi context
456func (StatMgr *OpenOltStatisticsMgr) convertGemStats(gemStats *openolt.GemPortStatistics) map[string]float32 {
457 gemStatsVal := make(map[string]float32)
458 gemStatsVal[IntfID] = float32(gemStats.IntfId)
459 gemStatsVal[GemID] = float32(gemStats.GemportId)
460 gemStatsVal[RxPackets] = float32(gemStats.RxPackets)
461 gemStatsVal[RxBytes] = float32(gemStats.RxBytes)
462 gemStatsVal[TxPackets] = float32(gemStats.TxPackets)
463 gemStatsVal[TxBytes] = float32(gemStats.TxBytes)
464 return gemStatsVal
465}
466
467// convertONUStats will convert onu stats response to kpi context
468func (StatMgr *OpenOltStatisticsMgr) convertONUStats(onuStats *openolt.OnuStatistics) map[string]float32 {
469 onuStatsVal := make(map[string]float32)
470 onuStatsVal[IntfID] = float32(onuStats.IntfId)
471 onuStatsVal[OnuID] = float32(onuStats.OnuId)
472 onuStatsVal[PositiveDrift] = float32(onuStats.PositiveDrift)
473 onuStatsVal[NegativeDrift] = float32(onuStats.NegativeDrift)
474 onuStatsVal[DelimiterMissDetection] = float32(onuStats.DelimiterMissDetection)
475 onuStatsVal[BipErrors] = float32(onuStats.BipErrors)
476 onuStatsVal[BipUnits] = float32(onuStats.BipUnits)
477 onuStatsVal[FecCorrectedSymbols] = float32(onuStats.FecCorrectedSymbols)
478 onuStatsVal[FecCodewordsCorrected] = float32(onuStats.FecCodewordsCorrected)
479 onuStatsVal[fecCodewordsUncorrectable] = float32(onuStats.FecCodewordsUncorrectable)
480 onuStatsVal[FecCodewords] = float32(onuStats.FecCodewords)
481 onuStatsVal[FecCorrectedUnits] = float32(onuStats.FecCorrectedUnits)
482 onuStatsVal[XGEMKeyErrors] = float32(onuStats.XgemKeyErrors)
483 onuStatsVal[XGEMLoss] = float32(onuStats.XgemLoss)
484 onuStatsVal[RxPloamsError] = float32(onuStats.RxPloamsError)
485 onuStatsVal[RxPloamsNonIdle] = float32(onuStats.RxPloamsNonIdle)
486 onuStatsVal[RxOmci] = float32(onuStats.RxOmci)
487 onuStatsVal[RxOmciPacketsCrcError] = float32(onuStats.RxOmciPacketsCrcError)
488 onuStatsVal[RxBytes] = float32(onuStats.RxBytes)
489 onuStatsVal[RxPackets] = float32(onuStats.RxPackets)
490 onuStatsVal[TxBytes] = float32(onuStats.TxBytes)
491 onuStatsVal[TxPackets] = float32(onuStats.TxPackets)
492 onuStatsVal[BerReported] = float32(onuStats.BerReported)
493 onuStatsVal[LcdgErrors] = float32(onuStats.LcdgErrors)
494 onuStatsVal[RdiErrors] = float32(onuStats.RdiErrors)
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530495 onuStatsVal[Timestamp] = float32(onuStats.Timestamp)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000496 return onuStatsVal
497}
498
499// collectOnuStats will collect the onu metrics
500func (StatMgr *OpenOltStatisticsMgr) collectOnuStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
501 onu := &openolt.Onu{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID}
502 logger.Debugw(ctx, "pulling-onu-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID})
503 if stats, err := StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
504 onuStats <- stats
505 } else {
506 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "err": err})
507 }
508}
509
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530510// collectOnDemandOnuStats will collect the onui-pon metrics
511func (StatMgr *OpenOltStatisticsMgr) collectOnDemandOnuStats(ctx context.Context, intfID uint32, onuID uint32) map[string]float32 {
512 onu := &openolt.Onu{IntfId: intfID, OnuId: onuID}
513 var stats *openolt.OnuStatistics
514 var err error
515 logger.Debugw(ctx, "pulling-onu-stats-on-demand", log.Fields{"IntfID": intfID, "OnuID": onuID})
516 if stats, err = StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
517 statValue := StatMgr.convertONUStats(stats)
518 return statValue
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530519 }
520 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": intfID, "OnuID": onuID, "err": err})
521 return nil
522}
523
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000524// collectOnuAndGemStats will collect both onu and gem metrics
525func (StatMgr *OpenOltStatisticsMgr) collectOnuAndGemStats(ctx context.Context, onuGemInfo []rsrcMgr.OnuGemInfo) {
526 if !StatMgr.Device.openOLT.enableONUStats && !StatMgr.Device.openOLT.enableGemStats {
527 return
528 }
529
530 for _, onuInfo := range onuGemInfo {
531 if StatMgr.Device.openOLT.enableONUStats {
532 go StatMgr.collectOnuStats(ctx, onuInfo)
533 }
534 if StatMgr.Device.openOLT.enableGemStats {
535 go StatMgr.collectGemStats(ctx, onuInfo)
536 }
537 }
538}
539
540// collectGemStats will collect gem metrics
541func (StatMgr *OpenOltStatisticsMgr) collectGemStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
542 for _, gem := range onuGemInfo.GemPorts {
543 logger.Debugw(ctx, "pulling-gem-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem})
544 onuPacket := &openolt.OnuPacket{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID, GemportId: gem}
545 if stats, err := StatMgr.Device.Client.GetGemPortStatistics(context.Background(), onuPacket); err == nil {
546 gemStats <- stats
547 } else {
548 logger.Errorw(ctx, "error-while-getting-gem-stats-for-onu",
549 log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem, "err": err})
550 }
551 }
552}
553
554// publishGemStats will publish the gem metrics
555func (StatMgr *OpenOltStatisticsMgr) publishGemStats() {
556 for {
557 statValue := StatMgr.convertGemStats(<-gemStats)
558 StatMgr.publishMetrics(context.Background(), GEMStats, statValue, &voltha.Port{Label: "GEM"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
559 }
560}
561
562// publishOnuStats will publish the onu metrics
563func (StatMgr *OpenOltStatisticsMgr) publishOnuStats() {
564 for {
565 statValue := StatMgr.convertONUStats(<-onuStats)
566 StatMgr.publishMetrics(context.Background(), ONUStats, statValue, &voltha.Port{Label: "ONU"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
567 }
568}
569
570// publishMetrics will publish the pon port metrics
kesavand62126212021-01-12 04:56:06 -0500571func (StatMgr *OpenOltStatisticsMgr) publishMetrics(ctx context.Context, statType string, val map[string]float32,
Girish Gowdra34815db2020-05-11 17:18:04 -0700572 port *voltha.Port, devID string, devType string) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573 logger.Debugw(ctx, "publish-metrics",
Shrey Baid26912972020-04-16 21:02:31 +0530574 log.Fields{
575 "port": port.Label,
576 "metrics": val})
Naga Manjunath7615e552019-10-11 22:35:47 +0530577
578 var metricInfo voltha.MetricInformation
579 var ke voltha.KpiEvent2
Esin Karamanccb714b2019-11-29 15:02:06 +0000580 var volthaEventSubCatgry voltha.EventSubCategory_Types
Girish Gowdra34815db2020-05-11 17:18:04 -0700581 metricsContext := make(map[string]string)
582 metricsContext["oltid"] = devID
583 metricsContext["devicetype"] = devType
584 metricsContext["portlabel"] = port.Label
Naga Manjunath7615e552019-10-11 22:35:47 +0530585
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000586 if statType == NNIStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530587 volthaEventSubCatgry = voltha.EventSubCategory_NNI
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000588 } else if statType == PONStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530589 volthaEventSubCatgry = voltha.EventSubCategory_PON
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000590 } else if statType == GEMStats || statType == ONUStats {
591 volthaEventSubCatgry = voltha.EventSubCategory_ONT
Naga Manjunath7615e552019-10-11 22:35:47 +0530592 }
593
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700594 raisedTs := time.Now().Unix()
Naga Manjunath7615e552019-10-11 22:35:47 +0530595 mmd := voltha.MetricMetaData{
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000596 Title: statType,
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700597 Ts: float64(raisedTs),
Girish Gowdra34815db2020-05-11 17:18:04 -0700598 Context: metricsContext,
Naga Manjunath7615e552019-10-11 22:35:47 +0530599 DeviceId: devID,
600 }
601
602 metricInfo.Metadata = &mmd
603 metricInfo.Metrics = val
604
605 ke.SliceData = []*voltha.MetricInformation{&metricInfo}
606 ke.Type = voltha.KpiEventType_slice
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700607 ke.Ts = float64(raisedTs)
Naga Manjunath7615e552019-10-11 22:35:47 +0530608
Himani Chawla473496d2021-12-01 00:10:30 +0530609 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 +0000610 logger.Errorw(ctx, "failed-to-send-stats", log.Fields{"err": err})
Naga Manjunath7615e552019-10-11 22:35:47 +0530611 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530612}
613
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700614// PortStatisticsIndication handles the port statistics indication
Neha Sharma96b7bf22020-06-15 10:37:32 +0000615func (StatMgr *OpenOltStatisticsMgr) PortStatisticsIndication(ctx context.Context, PortStats *openolt.PortStatistics, NumPonPorts uint32) {
616 StatMgr.PortsStatisticsKpis(ctx, PortStats, NumPonPorts)
617 logger.Debugw(ctx, "received-port-stats-indication", log.Fields{"port-stats": PortStats})
Akash Kankanala041a2122024-10-16 15:49:22 +0530618 // Indicate that PortStatisticsIndication is handled
619 // PortStats.IntfId is actually the port number
kesavand62126212021-01-12 04:56:06 -0500620 StatMgr.processStatIndication(ctx, portStatsType, PortStats.IntfId)
Abhilash S.L765ad002019-04-24 16:40:57 +0530621 // TODO send stats to core topic to the voltha kafka or a different kafka ?
622}
623
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700624// FlowStatisticsIndication to be implemented
Neha Sharma96b7bf22020-06-15 10:37:32 +0000625func FlowStatisticsIndication(ctx context.Context, self, FlowStats *openolt.FlowStatistics) {
626 logger.Debugw(ctx, "flow-stats-collected", log.Fields{"flow-stats": FlowStats})
Akash Kankanala041a2122024-10-16 15:49:22 +0530627 // TODO send to kafka ?
Abhilash S.L765ad002019-04-24 16:40:57 +0530628}
629
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700630// PortsStatisticsKpis map the port stats values into a dictionary, creates the kpiEvent and then publish to Kafka
Neha Sharma96b7bf22020-06-15 10:37:32 +0000631func (StatMgr *OpenOltStatisticsMgr) PortsStatisticsKpis(ctx context.Context, PortStats *openolt.PortStatistics, NumPonPorts uint32) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530632 /*map the port stats values into a dictionary
633 Create a kpoEvent and publish to Kafka
634
635 :param port_stats:
636 :return:
637 */
Akash Kankanala041a2122024-10-16 15:49:22 +0530638 // var err error
Abhilash S.L765ad002019-04-24 16:40:57 +0530639 IntfID := PortStats.IntfId
640
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700641 if (plt.IntfIDToPortNo(1, voltha.Port_ETHERNET_NNI) < IntfID) &&
642 (IntfID < plt.IntfIDToPortNo(4, voltha.Port_ETHERNET_NNI)) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530643 /*
644 for this release we are only interested in the first NNI for
645 Northbound.
646 we are not using the other 3
647 */
648 return
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700649 } else if plt.IntfIDToPortNo(0, voltha.Port_ETHERNET_NNI) == IntfID {
Naga Manjunath7615e552019-10-11 22:35:47 +0530650 var portNNIStat NniPort
651 portNNIStat.IntfID = IntfID
652 portNNIStat.PortNum = uint32(0)
653 portNNIStat.RxBytes = PortStats.RxBytes
654 portNNIStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000655 portNNIStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530656 portNNIStat.RxMcastPackets = PortStats.RxMcastPackets
657 portNNIStat.RxBcastPackets = PortStats.RxBcastPackets
658 portNNIStat.TxBytes = PortStats.TxBytes
659 portNNIStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000660 portNNIStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530661 portNNIStat.TxMcastPackets = PortStats.TxMcastPackets
662 portNNIStat.TxBcastPackets = PortStats.TxBcastPackets
663 mutex.Lock()
664 StatMgr.NorthBoundPort[0] = &portNNIStat
665 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000666 logger.Debugw(ctx, "received-nni-stats", log.Fields{"nni-stats": StatMgr.NorthBoundPort})
Naga Manjunath7615e552019-10-11 22:35:47 +0530667 }
668 for i := uint32(0); i < NumPonPorts; i++ {
Mahir Gunyel85f61c12021-10-06 11:53:45 -0700669 if plt.IntfIDToPortNo(i, voltha.Port_PON_OLT) == IntfID {
Naga Manjunath7615e552019-10-11 22:35:47 +0530670 var portPonStat PonPort
671 portPonStat.IntfID = IntfID
672 portPonStat.PortNum = i
673 portPonStat.PONID = i
674 portPonStat.RxBytes = PortStats.RxBytes
675 portPonStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000676 portPonStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530677 portPonStat.RxMcastPackets = PortStats.RxMcastPackets
678 portPonStat.RxBcastPackets = PortStats.RxBcastPackets
679 portPonStat.TxBytes = PortStats.TxBytes
680 portPonStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000681 portPonStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530682 portPonStat.TxMcastPackets = PortStats.TxMcastPackets
683 portPonStat.TxBcastPackets = PortStats.TxBcastPackets
684 mutex.Lock()
685 StatMgr.SouthBoundPort[i] = &portPonStat
686 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000687 logger.Debugw(ctx, "received-pon-stats-for-port", log.Fields{"port-pon-stats": portPonStat})
Naga Manjunath7615e552019-10-11 22:35:47 +0530688 }
689 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700690 /*
691 Based upon the intf_id map to an nni port or a pon port
692 the intf_id is the key to the north or south bound collections
693
694 Based upon the intf_id the port object (nni_port or pon_port) will
695 have its data attr. updated by the current dataset collected.
696
697 For prefixing the rule is currently to use the port number and not the intf_id
698 */
Akash Kankanala041a2122024-10-16 15:49:22 +0530699 // FIXME : Just use first NNI for now
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700700 /* TODO should the data be marshaled before sending it ?
701 if IntfID == IntfIdToPortNo(0, voltha.Port_ETHERNET_NNI) {
702 //NNI port (just the first one)
703 err = UpdatePortObjectKpiData(StatMgr.NorthBoundPorts[PortStats.IntfID], PMData)
704 } else {
705 //PON ports
706 err = UpdatePortObjectKpiData(SouthboundPorts[PortStats.IntfID], PMData)
707 }
708 if (err != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000709 logger.Error(ctx, "Error publishing statistics data")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700710 }
711 */
Abhilash S.L765ad002019-04-24 16:40:57 +0530712}
kesavand62126212021-01-12 04:56:06 -0500713
714func (StatMgr *OpenOltStatisticsMgr) updateGetOltPortCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
kesavand62126212021-01-12 04:56:06 -0500715 metrics := singleValResp.GetResponse().GetPortCoutners()
716 metrics.TxBytes = uint64(stats["TxBytes"])
717 metrics.RxBytes = uint64(stats["RxBytes"])
718 metrics.TxPackets = uint64(stats["TxPackets"])
719 metrics.RxPackets = uint64(stats["RxPackets"])
720 metrics.TxErrorPackets = uint64(stats["TxErrorPackets"])
721 metrics.RxErrorPackets = uint64(stats["RxErrorPackets"])
722 metrics.TxBcastPackets = uint64(stats["TxBcastPackets"])
723 metrics.RxBcastPackets = uint64(stats["RxBcastPackets"])
724 metrics.TxUcastPackets = uint64(stats["TxUcastPackets"])
725 metrics.RxUcastPackets = uint64(stats["RxUcastPackets"])
726 metrics.TxMcastPackets = uint64(stats["TxMcastPackets"])
727 metrics.RxMcastPackets = uint64(stats["RxMcastPackets"])
728
729 singleValResp.Response.Status = extension.GetValueResponse_OK
730 logger.Debugw(ctx, "updateGetOltPortCountersResponse", log.Fields{"resp": singleValResp})
731}
732
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400733// RegisterForStatIndication registers ch as a channel on which indication is sent when statistics of type t is received
kesavand62126212021-01-12 04:56:06 -0500734func (StatMgr *OpenOltStatisticsMgr) RegisterForStatIndication(ctx context.Context, t StatType, ch chan bool, portNo uint32, portType extension.GetOltPortCounters_PortType) {
735 statInd := statRegInfo{
736 chn: ch,
737 portNo: portNo,
738 portType: portType,
739 }
740
741 logger.Debugf(ctx, "RegisterForStatIndication stat type %v portno %v porttype %v chan %v", t, portNo, portType, ch)
742 StatMgr.statIndListnerMu.Lock()
743 StatMgr.statIndListners[t].PushBack(statInd)
744 StatMgr.statIndListnerMu.Unlock()
kesavand62126212021-01-12 04:56:06 -0500745}
746
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400747// DeRegisterFromStatIndication removes the previously registered channel ch for type t of statistics
kesavand62126212021-01-12 04:56:06 -0500748func (StatMgr *OpenOltStatisticsMgr) DeRegisterFromStatIndication(ctx context.Context, t StatType, ch chan bool) {
749 StatMgr.statIndListnerMu.Lock()
750 defer StatMgr.statIndListnerMu.Unlock()
751
752 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
753 statInd := e.Value.(statRegInfo)
754 if statInd.chn == ch {
755 StatMgr.statIndListners[t].Remove(e)
756 return
757 }
758 }
759}
760
761func (StatMgr *OpenOltStatisticsMgr) processStatIndication(ctx context.Context, t StatType, portNo uint32) {
762 var deRegList []*list.Element
763 var statInd statRegInfo
764
765 StatMgr.statIndListnerMu.Lock()
766 defer StatMgr.statIndListnerMu.Unlock()
767
768 if StatMgr.statIndListners[t] == nil || StatMgr.statIndListners[t].Len() == 0 {
769 logger.Debugf(ctx, "processStatIndication %v list is empty ", t)
770 return
771 }
772
773 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
774 statInd = e.Value.(statRegInfo)
775 if statInd.portNo != portNo {
776 fmt.Printf("Skipping %v\n", e.Value)
777 continue
778 }
779 // message sent
780 statInd.chn <- true
781 deRegList = append(deRegList, e)
kesavand62126212021-01-12 04:56:06 -0500782 }
783 for _, e := range deRegList {
784 StatMgr.statIndListners[t].Remove(e)
785 }
kesavand62126212021-01-12 04:56:06 -0500786}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530787
788func (StatMgr *OpenOltStatisticsMgr) updateGetOnuPonCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530789 metrics := singleValResp.GetResponse().GetOnuPonCounters()
790 metrics.IsIntfId = &extension.GetOnuCountersResponse_IntfId{
791 IntfId: uint32(stats[IntfID]),
792 }
793 metrics.IsOnuId = &extension.GetOnuCountersResponse_OnuId{
794 OnuId: uint32(stats[OnuID]),
795 }
796 metrics.IsPositiveDrift = &extension.GetOnuCountersResponse_PositiveDrift{
797 PositiveDrift: uint64(stats[PositiveDrift]),
798 }
799 metrics.IsNegativeDrift = &extension.GetOnuCountersResponse_NegativeDrift{
800 NegativeDrift: uint64(stats[NegativeDrift]),
801 }
802 metrics.IsDelimiterMissDetection = &extension.GetOnuCountersResponse_DelimiterMissDetection{
803 DelimiterMissDetection: uint64(stats[DelimiterMissDetection]),
804 }
805 metrics.IsBipErrors = &extension.GetOnuCountersResponse_BipErrors{
806 BipErrors: uint64(stats[BipErrors]),
807 }
808 metrics.IsBipUnits = &extension.GetOnuCountersResponse_BipUnits{
809 BipUnits: uint64(stats[BipUnits]),
810 }
811 metrics.IsFecCorrectedSymbols = &extension.GetOnuCountersResponse_FecCorrectedSymbols{
812 FecCorrectedSymbols: uint64(stats[FecCorrectedSymbols]),
813 }
814 metrics.IsFecCodewordsCorrected = &extension.GetOnuCountersResponse_FecCodewordsCorrected{
815 FecCodewordsCorrected: uint64(stats[FecCodewordsCorrected]),
816 }
817 metrics.IsFecCodewordsUncorrectable = &extension.GetOnuCountersResponse_FecCodewordsUncorrectable{
818 FecCodewordsUncorrectable: uint64(stats[fecCodewordsUncorrectable]),
819 }
820 metrics.IsFecCodewords = &extension.GetOnuCountersResponse_FecCodewords{
821 FecCodewords: uint64(stats[FecCodewords]),
822 }
823 metrics.IsFecCorrectedUnits = &extension.GetOnuCountersResponse_FecCorrectedUnits{
824 FecCorrectedUnits: uint64(stats[FecCorrectedUnits]),
825 }
826 metrics.IsXgemKeyErrors = &extension.GetOnuCountersResponse_XgemKeyErrors{
827 XgemKeyErrors: uint64(stats[XGEMKeyErrors]),
828 }
829 metrics.IsXgemLoss = &extension.GetOnuCountersResponse_XgemLoss{
830 XgemLoss: uint64(stats[XGEMLoss]),
831 }
832 metrics.IsRxPloamsError = &extension.GetOnuCountersResponse_RxPloamsError{
833 RxPloamsError: uint64(stats[RxPloamsError]),
834 }
835 metrics.IsRxPloamsNonIdle = &extension.GetOnuCountersResponse_RxPloamsNonIdle{
836 RxPloamsNonIdle: uint64(stats[RxPloamsNonIdle]),
837 }
838 metrics.IsRxOmci = &extension.GetOnuCountersResponse_RxOmci{
839 RxOmci: uint64(stats[RxOmci]),
840 }
841 metrics.IsRxOmciPacketsCrcError = &extension.GetOnuCountersResponse_RxOmciPacketsCrcError{
842 RxOmciPacketsCrcError: uint64(stats[RxOmciPacketsCrcError]),
843 }
844 metrics.IsRxBytes = &extension.GetOnuCountersResponse_RxBytes{
845 RxBytes: uint64(stats[RxBytes]),
846 }
847 metrics.IsRxPackets = &extension.GetOnuCountersResponse_RxPackets{
848 RxPackets: uint64(stats[RxPackets]),
849 }
850 metrics.IsTxBytes = &extension.GetOnuCountersResponse_TxBytes{
851 TxBytes: uint64(stats[TxBytes]),
852 }
853 metrics.IsTxPackets = &extension.GetOnuCountersResponse_TxPackets{
854 TxPackets: uint64(stats[TxPackets]),
855 }
856 metrics.IsBerReported = &extension.GetOnuCountersResponse_BerReported{
857 BerReported: uint64(stats[BerReported]),
858 }
859 metrics.IsLcdgErrors = &extension.GetOnuCountersResponse_LcdgErrors{
860 LcdgErrors: uint64(stats[LcdgErrors]),
861 }
862 metrics.IsRdiErrors = &extension.GetOnuCountersResponse_RdiErrors{
863 RdiErrors: uint64(stats[RdiErrors]),
864 }
865 metrics.IsTimestamp = &extension.GetOnuCountersResponse_Timestamp{
866 Timestamp: uint32(stats[Timestamp]),
867 }
868
869 singleValResp.Response.Status = extension.GetValueResponse_OK
870 logger.Debugw(ctx, "updateGetOnuPonCountersResponse", log.Fields{"resp": singleValResp})
871}