blob: 225742598e98efc71e77fb51e13da364cc5cfc49 [file] [log] [blame]
Abhilash S.L765ad002019-04-24 16:40:57 +05301/*
2 * Copyright 2019-present Open Networking Foundation
3
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
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package 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
khenaidoo106c61a2021-08-11 18:05:46 -040027 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
28
29 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Thomas Lee S94109f12020-03-03 16:39:29 +053030 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
khenaidoo106c61a2021-08-11 18:05:46 -040031 "github.com/opencord/voltha-protos/v5/go/extension"
32 "github.com/opencord/voltha-protos/v5/go/openolt"
33 "github.com/opencord/voltha-protos/v5/go/voltha"
Abhilash S.L765ad002019-04-24 16:40:57 +053034)
35
Gamze Abakafcbd6e72020-12-17 13:25:16 +000036const (
37 //NNIStats statType constant
38 NNIStats = "NNIStats"
39 //PONStats statType constant
40 PONStats = "PONStats"
41 //ONUStats statType constant
42 ONUStats = "ONUStats"
43 //GEMStats statType constant
44 GEMStats = "GEMStats"
45
46 //RxBytes constant
47 RxBytes = "RxBytes"
48 //RxPackets constant
49 RxPackets = "RxPackets"
50 //TxBytes constant
51 TxBytes = "TxBytes"
52 //TxPackets constant
53 TxPackets = "TxPackets"
54 //FecCodewords constant
55 FecCodewords = "FecCodewords"
56 //BipUnits constant
57 BipUnits = "BipUnits"
58 //BipErrors constant
59 BipErrors = "BipErrors"
60 //RxPloamsNonIdle constant
61 RxPloamsNonIdle = "RxPloamsNonIdle"
62 //RxPloamsError constant
63 RxPloamsError = "RxPloamsError"
64 //RxOmci constant
65 RxOmci = "RxOmci"
66 //RxOmciPacketsCrcError constant
67 RxOmciPacketsCrcError = "RxOmciPacketsCrcError"
68 //PositiveDrift constant
69 PositiveDrift = "PositiveDrift"
70 //NegativeDrift constant
71 NegativeDrift = "NegativeDrift"
72 //DelimiterMissDetection constant
73 DelimiterMissDetection = "DelimiterMissDetection"
74 //FecCorrectedSymbols constant
75 FecCorrectedSymbols = "FecCorrectedSymbols"
76 //FecCodewordsCorrected constant
77 FecCodewordsCorrected = "FecCodewordsCorrected"
78 //fecCodewordsUncorrectable constant
79 fecCodewordsUncorrectable = "fec_codewords_uncorrectable"
80 //FecCorrectedUnits constant
81 FecCorrectedUnits = "FecCorrectedUnits"
82 //XGEMKeyErrors constant
83 XGEMKeyErrors = "XGEMKeyErrors"
84 //XGEMLoss constant
85 XGEMLoss = "XGEMLOSS"
86 //BerReported constant
87 BerReported = "BerReported"
88 //LcdgErrors constant
89 LcdgErrors = "LcdgErrors"
90 //RdiErrors constant
91 RdiErrors = "RdiErrors"
Himani Chawla2c8ae0f2021-05-18 23:27:00 +053092 //Timestamp constant
93 Timestamp = "Timestamp"
Gamze Abakafcbd6e72020-12-17 13:25:16 +000094)
95
Naga Manjunath7615e552019-10-11 22:35:47 +053096var mutex = &sync.Mutex{}
97
Gamze Abakafcbd6e72020-12-17 13:25:16 +000098var onuStats = make(chan *openolt.OnuStatistics, 100)
99var gemStats = make(chan *openolt.GemPortStatistics, 100)
100
kesavand62126212021-01-12 04:56:06 -0500101//statRegInfo is used to register for notifications
102//on receiving port stats and flow stats indication
103type statRegInfo struct {
104 chn chan bool
105 portNo uint32
106 portType extension.GetOltPortCounters_PortType
107}
108
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700109// PonPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530110type PonPort struct {
111 /*
112 This is a highly reduced version taken from the adtran pon_port.
113 TODO: Extend for use in the openolt adapter set.
114 */
115 /* MAX_ONUS_SUPPORTED = 256
116 DEFAULT_ENABLED = False
117 MAX_DEPLOYMENT_RANGE = 25000 # Meters (OLT-PB maximum)
118
119 _MCAST_ONU_ID = 253
120 _MCAST_ALLOC_BASE = 0x500
121
122 _SUPPORTED_ACTIVATION_METHODS = ['autodiscovery'] # , 'autoactivate']
123 _SUPPORTED_AUTHENTICATION_METHODS = ['serial-number']
124 */
125 PONID uint32
126 DeviceID string
127 IntfID uint32
128 PortNum uint32
129 PortID uint32
130 Label string
131 ONUs map[uint32]interface{}
132 ONUsByID map[uint32]interface{}
133
134 RxBytes uint64
135 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000136 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530137 RxMcastPackets uint64
138 RxBcastPackets uint64
139 RxErrorPackets uint64
140 TxBytes uint64
141 TxPackets uint64
142 TxUcastPackets uint64
143 TxMcastPackets uint64
144 TxBcastPackets uint64
145 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000146 RxCrcErrors uint64
147 BipErrors uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530148}
149
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700150// NewPONPort returns a new instance of PonPort initialized with given PONID, DeviceID, IntfID and PortNum
Abhilash S.L765ad002019-04-24 16:40:57 +0530151func NewPONPort(PONID uint32, DeviceID string, IntfID uint32, PortNum uint32) *PonPort {
152
153 var PON PonPort
154
155 PON.PONID = PONID
156 PON.DeviceID = DeviceID
157 PON.IntfID = IntfID
158 PON.PortNum = PortNum
159 PON.PortID = 0
Naga Manjunath7615e552019-10-11 22:35:47 +0530160 PON.Label = fmt.Sprintf("%s%d", "pon-", PONID)
Abhilash S.L765ad002019-04-24 16:40:57 +0530161
162 PON.ONUs = make(map[uint32]interface{})
163 PON.ONUsByID = make(map[uint32]interface{})
164
165 /*
166 Statistics taken from nni_port
167 self.intf_id = 0 #handled by getter
168 self.port_no = 0 #handled by getter
169 self.port_id = 0 #handled by getter
170
171 Note: In the current implementation of the kpis coming from the BAL the stats are the
172 samne model for NNI and PON.
173
174 TODO: Integrate additional kpis for the PON and other southbound port objecgts.
175
176 */
177
178 PON.RxBytes = 0
179 PON.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000180 PON.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530181 PON.RxMcastPackets = 0
182 PON.RxBcastPackets = 0
183 PON.RxErrorPackets = 0
184 PON.TxBytes = 0
185 PON.TxPackets = 0
186 PON.TxUcastPackets = 0
187 PON.TxMcastPackets = 0
188 PON.TxBcastPackets = 0
189 PON.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000190 PON.RxCrcErrors = 0
191 PON.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530192
193 /* def __str__(self):
194 return "PonPort-{}: Admin: {}, Oper: {}, OLT: {}".format(self._label,
195 self._admin_state,
196 self._oper_status,
197 self.olt)
198 */
199 return &PON
200}
201
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700202// NniPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530203type NniPort struct {
204 /*
205 Northbound network port, often Ethernet-based
206
207 This is a highly reduced version taken from the adtran nni_port code set
208 TODO: add functions to allow for port specific values and operations
209 */
210 PortNum uint32
211 Name string
212 LogicalPort uint32
213 IntfID uint32
214
215 RxBytes uint64
216 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000217 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530218 RxMcastPackets uint64
219 RxBcastPackets uint64
220 RxErrorPackets uint64
221 TxBytes uint64
222 TxPackets uint64
223 TxUcastPackets uint64
224 TxMcastPackets uint64
225 TxBcastPackets uint64
226 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000227 RxCrcErrors uint64
228 BipErrors uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530229}
230
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700231// NewNniPort returns a new instance of NniPort initialized with the given PortNum and IntfID
Abhilash S.L765ad002019-04-24 16:40:57 +0530232func NewNniPort(PortNum uint32, IntfID uint32) *NniPort {
233
234 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
kesavand62126212021-01-12 04:56:06 -0500258//StatType defines portStatsType and flowStatsType types
259type 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 {
268 Device *DeviceHandler
Naga Manjunath7615e552019-10-11 22:35:47 +0530269 NorthBoundPort map[uint32]*NniPort
270 SouthBoundPort map[uint32]*PonPort
Abhilash S.L765ad002019-04-24 16:40:57 +0530271 // TODO PMMetrics Metrics
kesavand62126212021-01-12 04:56:06 -0500272 //statIndListners is the list of requests to be notified when port and flow stats indication is received
273 statIndListnerMu sync.Mutex
274 statIndListners map[StatType]*list.List
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
280 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)
Naga Manjunath7615e552019-10-11 22:35:47 +0530329 PONPorts[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
349 //This builds a port object which is added to the
350 //appropriate northbound or southbound values
351 if IntfType == "nni" {
Naga Manjunath7615e552019-10-11 22:35:47 +0530352 IntfID := IntfIDToPortNo(PortNum, voltha.Port_ETHERNET_NNI)
353 nniID := 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.
Naga Manjunath7615e552019-10-11 22:35:47 +0530362 IntfID := IntfIDToPortNo(PortNum, voltha.Port_PON_OLT)
363 PONID := 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 {
377
378 nnival := make(map[string]float32)
379 mutex.Lock()
380 cm := StatMgr.Device.portStats.NorthBoundPort[nniID]
381 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000382 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530383
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000384 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400385 for metric := range metricNames {
386 if metricNames[metric].Enabled {
387 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530388 }
389 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000390
391 for _, mName := range metrics {
392 switch mName {
393 case "rx_bytes":
394 nnival["RxBytes"] = float32(cm.RxBytes)
395 case "rx_packets":
396 nnival["RxPackets"] = float32(cm.RxPackets)
397 case "rx_ucast_packets":
398 nnival["RxUcastPackets"] = float32(cm.RxUcastPackets)
399 case "rx_mcast_packets":
400 nnival["RxMcastPackets"] = float32(cm.RxMcastPackets)
401 case "rx_bcast_packets":
402 nnival["RxBcastPackets"] = float32(cm.RxBcastPackets)
403 case "tx_bytes":
404 nnival["TxBytes"] = float32(cm.TxBytes)
405 case "tx_packets":
406 nnival["TxPackets"] = float32(cm.TxPackets)
407 case "tx_mcast_packets":
408 nnival["TxMcastPackets"] = float32(cm.TxMcastPackets)
409 case "tx_bcast_packets":
410 nnival["TxBcastPackets"] = float32(cm.TxBcastPackets)
411 }
412 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530413 return nnival
414}
415
416// collectPONMetrics will collect the pon port metrics
417func (StatMgr *OpenOltStatisticsMgr) collectPONMetrics(pID uint32) map[string]float32 {
418
419 ponval := make(map[string]float32)
420 mutex.Lock()
421 cm := StatMgr.Device.portStats.SouthBoundPort[pID]
422 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000423 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530424
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000425 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400426 for metric := range metricNames {
427 if metricNames[metric].Enabled {
428 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530429 }
430 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000431
432 for _, mName := range metrics {
433 switch mName {
434 case "rx_bytes":
435 ponval["RxBytes"] = float32(cm.RxBytes)
436 case "rx_packets":
437 ponval["RxPackets"] = float32(cm.RxPackets)
438 case "rx_ucast_packets":
439 ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
440 case "rx_mcast_packets":
441 ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
442 case "rx_bcast_packets":
443 ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
444 case "tx_bytes":
445 ponval["TxBytes"] = float32(cm.TxBytes)
446 case "tx_packets":
447 ponval["TxPackets"] = float32(cm.TxPackets)
448 case "tx_mcast_packets":
449 ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
450 case "tx_bcast_packets":
451 ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
452 }
453 }
454
Naga Manjunath7615e552019-10-11 22:35:47 +0530455 return ponval
456}
457
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000458// converGemStats will convert gem stats response to kpi context
459func (StatMgr *OpenOltStatisticsMgr) convertGemStats(gemStats *openolt.GemPortStatistics) map[string]float32 {
460 gemStatsVal := make(map[string]float32)
461 gemStatsVal[IntfID] = float32(gemStats.IntfId)
462 gemStatsVal[GemID] = float32(gemStats.GemportId)
463 gemStatsVal[RxPackets] = float32(gemStats.RxPackets)
464 gemStatsVal[RxBytes] = float32(gemStats.RxBytes)
465 gemStatsVal[TxPackets] = float32(gemStats.TxPackets)
466 gemStatsVal[TxBytes] = float32(gemStats.TxBytes)
467 return gemStatsVal
468}
469
470// convertONUStats will convert onu stats response to kpi context
471func (StatMgr *OpenOltStatisticsMgr) convertONUStats(onuStats *openolt.OnuStatistics) map[string]float32 {
472 onuStatsVal := make(map[string]float32)
473 onuStatsVal[IntfID] = float32(onuStats.IntfId)
474 onuStatsVal[OnuID] = float32(onuStats.OnuId)
475 onuStatsVal[PositiveDrift] = float32(onuStats.PositiveDrift)
476 onuStatsVal[NegativeDrift] = float32(onuStats.NegativeDrift)
477 onuStatsVal[DelimiterMissDetection] = float32(onuStats.DelimiterMissDetection)
478 onuStatsVal[BipErrors] = float32(onuStats.BipErrors)
479 onuStatsVal[BipUnits] = float32(onuStats.BipUnits)
480 onuStatsVal[FecCorrectedSymbols] = float32(onuStats.FecCorrectedSymbols)
481 onuStatsVal[FecCodewordsCorrected] = float32(onuStats.FecCodewordsCorrected)
482 onuStatsVal[fecCodewordsUncorrectable] = float32(onuStats.FecCodewordsUncorrectable)
483 onuStatsVal[FecCodewords] = float32(onuStats.FecCodewords)
484 onuStatsVal[FecCorrectedUnits] = float32(onuStats.FecCorrectedUnits)
485 onuStatsVal[XGEMKeyErrors] = float32(onuStats.XgemKeyErrors)
486 onuStatsVal[XGEMLoss] = float32(onuStats.XgemLoss)
487 onuStatsVal[RxPloamsError] = float32(onuStats.RxPloamsError)
488 onuStatsVal[RxPloamsNonIdle] = float32(onuStats.RxPloamsNonIdle)
489 onuStatsVal[RxOmci] = float32(onuStats.RxOmci)
490 onuStatsVal[RxOmciPacketsCrcError] = float32(onuStats.RxOmciPacketsCrcError)
491 onuStatsVal[RxBytes] = float32(onuStats.RxBytes)
492 onuStatsVal[RxPackets] = float32(onuStats.RxPackets)
493 onuStatsVal[TxBytes] = float32(onuStats.TxBytes)
494 onuStatsVal[TxPackets] = float32(onuStats.TxPackets)
495 onuStatsVal[BerReported] = float32(onuStats.BerReported)
496 onuStatsVal[LcdgErrors] = float32(onuStats.LcdgErrors)
497 onuStatsVal[RdiErrors] = float32(onuStats.RdiErrors)
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530498 onuStatsVal[Timestamp] = float32(onuStats.Timestamp)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000499 return onuStatsVal
500}
501
502// collectOnuStats will collect the onu metrics
503func (StatMgr *OpenOltStatisticsMgr) collectOnuStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
504 onu := &openolt.Onu{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID}
505 logger.Debugw(ctx, "pulling-onu-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID})
506 if stats, err := StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
507 onuStats <- stats
508 } else {
509 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "err": err})
510 }
511}
512
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530513// collectOnDemandOnuStats will collect the onui-pon metrics
514func (StatMgr *OpenOltStatisticsMgr) collectOnDemandOnuStats(ctx context.Context, intfID uint32, onuID uint32) map[string]float32 {
515 onu := &openolt.Onu{IntfId: intfID, OnuId: onuID}
516 var stats *openolt.OnuStatistics
517 var err error
518 logger.Debugw(ctx, "pulling-onu-stats-on-demand", log.Fields{"IntfID": intfID, "OnuID": onuID})
519 if stats, err = StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
520 statValue := StatMgr.convertONUStats(stats)
521 return statValue
522
523 }
524 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": intfID, "OnuID": onuID, "err": err})
525 return nil
526}
527
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000528// collectOnuAndGemStats will collect both onu and gem metrics
529func (StatMgr *OpenOltStatisticsMgr) collectOnuAndGemStats(ctx context.Context, onuGemInfo []rsrcMgr.OnuGemInfo) {
530 if !StatMgr.Device.openOLT.enableONUStats && !StatMgr.Device.openOLT.enableGemStats {
531 return
532 }
533
534 for _, onuInfo := range onuGemInfo {
535 if StatMgr.Device.openOLT.enableONUStats {
536 go StatMgr.collectOnuStats(ctx, onuInfo)
537 }
538 if StatMgr.Device.openOLT.enableGemStats {
539 go StatMgr.collectGemStats(ctx, onuInfo)
540 }
541 }
542}
543
544// collectGemStats will collect gem metrics
545func (StatMgr *OpenOltStatisticsMgr) collectGemStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
546 for _, gem := range onuGemInfo.GemPorts {
547 logger.Debugw(ctx, "pulling-gem-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem})
548 onuPacket := &openolt.OnuPacket{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID, GemportId: gem}
549 if stats, err := StatMgr.Device.Client.GetGemPortStatistics(context.Background(), onuPacket); err == nil {
550 gemStats <- stats
551 } else {
552 logger.Errorw(ctx, "error-while-getting-gem-stats-for-onu",
553 log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem, "err": err})
554 }
555 }
556}
557
558// publishGemStats will publish the gem metrics
559func (StatMgr *OpenOltStatisticsMgr) publishGemStats() {
560 for {
561 statValue := StatMgr.convertGemStats(<-gemStats)
562 StatMgr.publishMetrics(context.Background(), GEMStats, statValue, &voltha.Port{Label: "GEM"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
563 }
564}
565
566// publishOnuStats will publish the onu metrics
567func (StatMgr *OpenOltStatisticsMgr) publishOnuStats() {
568 for {
569 statValue := StatMgr.convertONUStats(<-onuStats)
570 StatMgr.publishMetrics(context.Background(), ONUStats, statValue, &voltha.Port{Label: "ONU"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
571 }
572}
573
574// publishMetrics will publish the pon port metrics
kesavand62126212021-01-12 04:56:06 -0500575func (StatMgr *OpenOltStatisticsMgr) publishMetrics(ctx context.Context, statType string, val map[string]float32,
Girish Gowdra34815db2020-05-11 17:18:04 -0700576 port *voltha.Port, devID string, devType string) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000577 logger.Debugw(ctx, "publish-metrics",
Shrey Baid26912972020-04-16 21:02:31 +0530578 log.Fields{
579 "port": port.Label,
580 "metrics": val})
Naga Manjunath7615e552019-10-11 22:35:47 +0530581
582 var metricInfo voltha.MetricInformation
583 var ke voltha.KpiEvent2
Esin Karamanccb714b2019-11-29 15:02:06 +0000584 var volthaEventSubCatgry voltha.EventSubCategory_Types
Girish Gowdra34815db2020-05-11 17:18:04 -0700585 metricsContext := make(map[string]string)
586 metricsContext["oltid"] = devID
587 metricsContext["devicetype"] = devType
588 metricsContext["portlabel"] = port.Label
Naga Manjunath7615e552019-10-11 22:35:47 +0530589
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000590 if statType == NNIStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530591 volthaEventSubCatgry = voltha.EventSubCategory_NNI
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000592 } else if statType == PONStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530593 volthaEventSubCatgry = voltha.EventSubCategory_PON
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000594 } else if statType == GEMStats || statType == ONUStats {
595 volthaEventSubCatgry = voltha.EventSubCategory_ONT
Naga Manjunath7615e552019-10-11 22:35:47 +0530596 }
597
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700598 raisedTs := time.Now().Unix()
Naga Manjunath7615e552019-10-11 22:35:47 +0530599 mmd := voltha.MetricMetaData{
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000600 Title: statType,
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700601 Ts: float64(raisedTs),
Girish Gowdra34815db2020-05-11 17:18:04 -0700602 Context: metricsContext,
Naga Manjunath7615e552019-10-11 22:35:47 +0530603 DeviceId: devID,
604 }
605
606 metricInfo.Metadata = &mmd
607 metricInfo.Metrics = val
608
609 ke.SliceData = []*voltha.MetricInformation{&metricInfo}
610 ke.Type = voltha.KpiEventType_slice
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700611 ke.Ts = float64(raisedTs)
Naga Manjunath7615e552019-10-11 22:35:47 +0530612
Neha Sharma96b7bf22020-06-15 10:37:32 +0000613 if err := StatMgr.Device.EventProxy.SendKpiEvent(ctx, "STATS_EVENT", &ke, voltha.EventCategory_EQUIPMENT, volthaEventSubCatgry, raisedTs); err != nil {
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000614 logger.Errorw(ctx, "failed-to-send-stats", log.Fields{"err": err})
Naga Manjunath7615e552019-10-11 22:35:47 +0530615 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530616}
617
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700618// PortStatisticsIndication handles the port statistics indication
Neha Sharma96b7bf22020-06-15 10:37:32 +0000619func (StatMgr *OpenOltStatisticsMgr) PortStatisticsIndication(ctx context.Context, PortStats *openolt.PortStatistics, NumPonPorts uint32) {
620 StatMgr.PortsStatisticsKpis(ctx, PortStats, NumPonPorts)
621 logger.Debugw(ctx, "received-port-stats-indication", log.Fields{"port-stats": PortStats})
kesavand62126212021-01-12 04:56:06 -0500622 //Indicate that PortStatisticsIndication is handled
623 //PortStats.IntfId is actually the port number
624 StatMgr.processStatIndication(ctx, portStatsType, PortStats.IntfId)
Abhilash S.L765ad002019-04-24 16:40:57 +0530625 // TODO send stats to core topic to the voltha kafka or a different kafka ?
626}
627
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700628// FlowStatisticsIndication to be implemented
Neha Sharma96b7bf22020-06-15 10:37:32 +0000629func FlowStatisticsIndication(ctx context.Context, self, FlowStats *openolt.FlowStatistics) {
630 logger.Debugw(ctx, "flow-stats-collected", log.Fields{"flow-stats": FlowStats})
Abhilash S.L765ad002019-04-24 16:40:57 +0530631 //TODO send to kafka ?
632}
633
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700634// PortsStatisticsKpis map the port stats values into a dictionary, creates the kpiEvent and then publish to Kafka
Neha Sharma96b7bf22020-06-15 10:37:32 +0000635func (StatMgr *OpenOltStatisticsMgr) PortsStatisticsKpis(ctx context.Context, PortStats *openolt.PortStatistics, NumPonPorts uint32) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530636
637 /*map the port stats values into a dictionary
638 Create a kpoEvent and publish to Kafka
639
640 :param port_stats:
641 :return:
642 */
643 //var err error
644 IntfID := PortStats.IntfId
645
Naga Manjunath7615e552019-10-11 22:35:47 +0530646 if (IntfIDToPortNo(1, voltha.Port_ETHERNET_NNI) < IntfID) &&
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700647 (IntfID < IntfIDToPortNo(4, voltha.Port_ETHERNET_NNI)) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530648 /*
649 for this release we are only interested in the first NNI for
650 Northbound.
651 we are not using the other 3
652 */
653 return
Naga Manjunath7615e552019-10-11 22:35:47 +0530654 } else if IntfIDToPortNo(0, voltha.Port_ETHERNET_NNI) == IntfID {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700655
Naga Manjunath7615e552019-10-11 22:35:47 +0530656 var portNNIStat NniPort
657 portNNIStat.IntfID = IntfID
658 portNNIStat.PortNum = uint32(0)
659 portNNIStat.RxBytes = PortStats.RxBytes
660 portNNIStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000661 portNNIStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530662 portNNIStat.RxMcastPackets = PortStats.RxMcastPackets
663 portNNIStat.RxBcastPackets = PortStats.RxBcastPackets
664 portNNIStat.TxBytes = PortStats.TxBytes
665 portNNIStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000666 portNNIStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530667 portNNIStat.TxMcastPackets = PortStats.TxMcastPackets
668 portNNIStat.TxBcastPackets = PortStats.TxBcastPackets
669 mutex.Lock()
670 StatMgr.NorthBoundPort[0] = &portNNIStat
671 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000672 logger.Debugw(ctx, "received-nni-stats", log.Fields{"nni-stats": StatMgr.NorthBoundPort})
Naga Manjunath7615e552019-10-11 22:35:47 +0530673 }
674 for i := uint32(0); i < NumPonPorts; i++ {
675
676 if IntfIDToPortNo(i, voltha.Port_PON_OLT) == IntfID {
677 var portPonStat PonPort
678 portPonStat.IntfID = IntfID
679 portPonStat.PortNum = i
680 portPonStat.PONID = i
681 portPonStat.RxBytes = PortStats.RxBytes
682 portPonStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000683 portPonStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530684 portPonStat.RxMcastPackets = PortStats.RxMcastPackets
685 portPonStat.RxBcastPackets = PortStats.RxBcastPackets
686 portPonStat.TxBytes = PortStats.TxBytes
687 portPonStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000688 portPonStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530689 portPonStat.TxMcastPackets = PortStats.TxMcastPackets
690 portPonStat.TxBcastPackets = PortStats.TxBcastPackets
691 mutex.Lock()
692 StatMgr.SouthBoundPort[i] = &portPonStat
693 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000694 logger.Debugw(ctx, "received-pon-stats-for-port", log.Fields{"port-pon-stats": portPonStat})
Naga Manjunath7615e552019-10-11 22:35:47 +0530695 }
696 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700697
698 /*
699 Based upon the intf_id map to an nni port or a pon port
700 the intf_id is the key to the north or south bound collections
701
702 Based upon the intf_id the port object (nni_port or pon_port) will
703 have its data attr. updated by the current dataset collected.
704
705 For prefixing the rule is currently to use the port number and not the intf_id
706 */
707 //FIXME : Just use first NNI for now
708 /* TODO should the data be marshaled before sending it ?
709 if IntfID == IntfIdToPortNo(0, voltha.Port_ETHERNET_NNI) {
710 //NNI port (just the first one)
711 err = UpdatePortObjectKpiData(StatMgr.NorthBoundPorts[PortStats.IntfID], PMData)
712 } else {
713 //PON ports
714 err = UpdatePortObjectKpiData(SouthboundPorts[PortStats.IntfID], PMData)
715 }
716 if (err != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 logger.Error(ctx, "Error publishing statistics data")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700718 }
719 */
720
Abhilash S.L765ad002019-04-24 16:40:57 +0530721}
kesavand62126212021-01-12 04:56:06 -0500722
723func (StatMgr *OpenOltStatisticsMgr) updateGetOltPortCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
724
725 metrics := singleValResp.GetResponse().GetPortCoutners()
726 metrics.TxBytes = uint64(stats["TxBytes"])
727 metrics.RxBytes = uint64(stats["RxBytes"])
728 metrics.TxPackets = uint64(stats["TxPackets"])
729 metrics.RxPackets = uint64(stats["RxPackets"])
730 metrics.TxErrorPackets = uint64(stats["TxErrorPackets"])
731 metrics.RxErrorPackets = uint64(stats["RxErrorPackets"])
732 metrics.TxBcastPackets = uint64(stats["TxBcastPackets"])
733 metrics.RxBcastPackets = uint64(stats["RxBcastPackets"])
734 metrics.TxUcastPackets = uint64(stats["TxUcastPackets"])
735 metrics.RxUcastPackets = uint64(stats["RxUcastPackets"])
736 metrics.TxMcastPackets = uint64(stats["TxMcastPackets"])
737 metrics.RxMcastPackets = uint64(stats["RxMcastPackets"])
738
739 singleValResp.Response.Status = extension.GetValueResponse_OK
740 logger.Debugw(ctx, "updateGetOltPortCountersResponse", log.Fields{"resp": singleValResp})
741}
742
743//RegisterForStatIndication registers ch as a channel on which indication is sent when statistics of type t is received
744func (StatMgr *OpenOltStatisticsMgr) RegisterForStatIndication(ctx context.Context, t StatType, ch chan bool, portNo uint32, portType extension.GetOltPortCounters_PortType) {
745 statInd := statRegInfo{
746 chn: ch,
747 portNo: portNo,
748 portType: portType,
749 }
750
751 logger.Debugf(ctx, "RegisterForStatIndication stat type %v portno %v porttype %v chan %v", t, portNo, portType, ch)
752 StatMgr.statIndListnerMu.Lock()
753 StatMgr.statIndListners[t].PushBack(statInd)
754 StatMgr.statIndListnerMu.Unlock()
755
756}
757
758//DeRegisterFromStatIndication removes the previously registered channel ch for type t of statistics
759func (StatMgr *OpenOltStatisticsMgr) DeRegisterFromStatIndication(ctx context.Context, t StatType, ch chan bool) {
760 StatMgr.statIndListnerMu.Lock()
761 defer StatMgr.statIndListnerMu.Unlock()
762
763 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
764 statInd := e.Value.(statRegInfo)
765 if statInd.chn == ch {
766 StatMgr.statIndListners[t].Remove(e)
767 return
768 }
769 }
770}
771
772func (StatMgr *OpenOltStatisticsMgr) processStatIndication(ctx context.Context, t StatType, portNo uint32) {
773 var deRegList []*list.Element
774 var statInd statRegInfo
775
776 StatMgr.statIndListnerMu.Lock()
777 defer StatMgr.statIndListnerMu.Unlock()
778
779 if StatMgr.statIndListners[t] == nil || StatMgr.statIndListners[t].Len() == 0 {
780 logger.Debugf(ctx, "processStatIndication %v list is empty ", t)
781 return
782 }
783
784 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
785 statInd = e.Value.(statRegInfo)
786 if statInd.portNo != portNo {
787 fmt.Printf("Skipping %v\n", e.Value)
788 continue
789 }
790 // message sent
791 statInd.chn <- true
792 deRegList = append(deRegList, e)
793
794 }
795 for _, e := range deRegList {
796 StatMgr.statIndListners[t].Remove(e)
797 }
798
799}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530800
801func (StatMgr *OpenOltStatisticsMgr) updateGetOnuPonCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
802
803 metrics := singleValResp.GetResponse().GetOnuPonCounters()
804 metrics.IsIntfId = &extension.GetOnuCountersResponse_IntfId{
805 IntfId: uint32(stats[IntfID]),
806 }
807 metrics.IsOnuId = &extension.GetOnuCountersResponse_OnuId{
808 OnuId: uint32(stats[OnuID]),
809 }
810 metrics.IsPositiveDrift = &extension.GetOnuCountersResponse_PositiveDrift{
811 PositiveDrift: uint64(stats[PositiveDrift]),
812 }
813 metrics.IsNegativeDrift = &extension.GetOnuCountersResponse_NegativeDrift{
814 NegativeDrift: uint64(stats[NegativeDrift]),
815 }
816 metrics.IsDelimiterMissDetection = &extension.GetOnuCountersResponse_DelimiterMissDetection{
817 DelimiterMissDetection: uint64(stats[DelimiterMissDetection]),
818 }
819 metrics.IsBipErrors = &extension.GetOnuCountersResponse_BipErrors{
820 BipErrors: uint64(stats[BipErrors]),
821 }
822 metrics.IsBipUnits = &extension.GetOnuCountersResponse_BipUnits{
823 BipUnits: uint64(stats[BipUnits]),
824 }
825 metrics.IsFecCorrectedSymbols = &extension.GetOnuCountersResponse_FecCorrectedSymbols{
826 FecCorrectedSymbols: uint64(stats[FecCorrectedSymbols]),
827 }
828 metrics.IsFecCodewordsCorrected = &extension.GetOnuCountersResponse_FecCodewordsCorrected{
829 FecCodewordsCorrected: uint64(stats[FecCodewordsCorrected]),
830 }
831 metrics.IsFecCodewordsUncorrectable = &extension.GetOnuCountersResponse_FecCodewordsUncorrectable{
832 FecCodewordsUncorrectable: uint64(stats[fecCodewordsUncorrectable]),
833 }
834 metrics.IsFecCodewords = &extension.GetOnuCountersResponse_FecCodewords{
835 FecCodewords: uint64(stats[FecCodewords]),
836 }
837 metrics.IsFecCorrectedUnits = &extension.GetOnuCountersResponse_FecCorrectedUnits{
838 FecCorrectedUnits: uint64(stats[FecCorrectedUnits]),
839 }
840 metrics.IsXgemKeyErrors = &extension.GetOnuCountersResponse_XgemKeyErrors{
841 XgemKeyErrors: uint64(stats[XGEMKeyErrors]),
842 }
843 metrics.IsXgemLoss = &extension.GetOnuCountersResponse_XgemLoss{
844 XgemLoss: uint64(stats[XGEMLoss]),
845 }
846 metrics.IsRxPloamsError = &extension.GetOnuCountersResponse_RxPloamsError{
847 RxPloamsError: uint64(stats[RxPloamsError]),
848 }
849 metrics.IsRxPloamsNonIdle = &extension.GetOnuCountersResponse_RxPloamsNonIdle{
850 RxPloamsNonIdle: uint64(stats[RxPloamsNonIdle]),
851 }
852 metrics.IsRxOmci = &extension.GetOnuCountersResponse_RxOmci{
853 RxOmci: uint64(stats[RxOmci]),
854 }
855 metrics.IsRxOmciPacketsCrcError = &extension.GetOnuCountersResponse_RxOmciPacketsCrcError{
856 RxOmciPacketsCrcError: uint64(stats[RxOmciPacketsCrcError]),
857 }
858 metrics.IsRxBytes = &extension.GetOnuCountersResponse_RxBytes{
859 RxBytes: uint64(stats[RxBytes]),
860 }
861 metrics.IsRxPackets = &extension.GetOnuCountersResponse_RxPackets{
862 RxPackets: uint64(stats[RxPackets]),
863 }
864 metrics.IsTxBytes = &extension.GetOnuCountersResponse_TxBytes{
865 TxBytes: uint64(stats[TxBytes]),
866 }
867 metrics.IsTxPackets = &extension.GetOnuCountersResponse_TxPackets{
868 TxPackets: uint64(stats[TxPackets]),
869 }
870 metrics.IsBerReported = &extension.GetOnuCountersResponse_BerReported{
871 BerReported: uint64(stats[BerReported]),
872 }
873 metrics.IsLcdgErrors = &extension.GetOnuCountersResponse_LcdgErrors{
874 LcdgErrors: uint64(stats[LcdgErrors]),
875 }
876 metrics.IsRdiErrors = &extension.GetOnuCountersResponse_RdiErrors{
877 RdiErrors: uint64(stats[RdiErrors]),
878 }
879 metrics.IsTimestamp = &extension.GetOnuCountersResponse_Timestamp{
880 Timestamp: uint32(stats[Timestamp]),
881 }
882
883 singleValResp.Response.Status = extension.GetValueResponse_OK
884 logger.Debugw(ctx, "updateGetOnuPonCountersResponse", log.Fields{"resp": singleValResp})
885}