blob: 42c60d7c4e7d0a643de9643127e97497ce46804e [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"
Gamze Abakafcbd6e72020-12-17 13:25:16 +000024 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Shrey Baid26912972020-04-16 21:02:31 +053025 "sync"
26 "time"
27
Girish Gowdraa09aeab2020-09-14 16:30:52 -070028 "github.com/opencord/voltha-lib-go/v4/pkg/log"
Thomas Lee S94109f12020-03-03 16:39:29 +053029 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
kesavand62126212021-01-12 04:56:06 -050030 "github.com/opencord/voltha-protos/v4/go/extension"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070031 "github.com/opencord/voltha-protos/v4/go/openolt"
32 "github.com/opencord/voltha-protos/v4/go/voltha"
Abhilash S.L765ad002019-04-24 16:40:57 +053033)
34
Gamze Abakafcbd6e72020-12-17 13:25:16 +000035const (
36 //NNIStats statType constant
37 NNIStats = "NNIStats"
38 //PONStats statType constant
39 PONStats = "PONStats"
40 //ONUStats statType constant
41 ONUStats = "ONUStats"
42 //GEMStats statType constant
43 GEMStats = "GEMStats"
44
45 //RxBytes constant
46 RxBytes = "RxBytes"
47 //RxPackets constant
48 RxPackets = "RxPackets"
49 //TxBytes constant
50 TxBytes = "TxBytes"
51 //TxPackets constant
52 TxPackets = "TxPackets"
53 //FecCodewords constant
54 FecCodewords = "FecCodewords"
55 //BipUnits constant
56 BipUnits = "BipUnits"
57 //BipErrors constant
58 BipErrors = "BipErrors"
59 //RxPloamsNonIdle constant
60 RxPloamsNonIdle = "RxPloamsNonIdle"
61 //RxPloamsError constant
62 RxPloamsError = "RxPloamsError"
63 //RxOmci constant
64 RxOmci = "RxOmci"
65 //RxOmciPacketsCrcError constant
66 RxOmciPacketsCrcError = "RxOmciPacketsCrcError"
67 //PositiveDrift constant
68 PositiveDrift = "PositiveDrift"
69 //NegativeDrift constant
70 NegativeDrift = "NegativeDrift"
71 //DelimiterMissDetection constant
72 DelimiterMissDetection = "DelimiterMissDetection"
73 //FecCorrectedSymbols constant
74 FecCorrectedSymbols = "FecCorrectedSymbols"
75 //FecCodewordsCorrected constant
76 FecCodewordsCorrected = "FecCodewordsCorrected"
77 //fecCodewordsUncorrectable constant
78 fecCodewordsUncorrectable = "fec_codewords_uncorrectable"
79 //FecCorrectedUnits constant
80 FecCorrectedUnits = "FecCorrectedUnits"
81 //XGEMKeyErrors constant
82 XGEMKeyErrors = "XGEMKeyErrors"
83 //XGEMLoss constant
84 XGEMLoss = "XGEMLOSS"
85 //BerReported constant
86 BerReported = "BerReported"
87 //LcdgErrors constant
88 LcdgErrors = "LcdgErrors"
89 //RdiErrors constant
90 RdiErrors = "RdiErrors"
Himani Chawla2c8ae0f2021-05-18 23:27:00 +053091 //Timestamp constant
92 Timestamp = "Timestamp"
Gamze Abakafcbd6e72020-12-17 13:25:16 +000093)
94
Naga Manjunath7615e552019-10-11 22:35:47 +053095var mutex = &sync.Mutex{}
96
Gamze Abakafcbd6e72020-12-17 13:25:16 +000097var onuStats = make(chan *openolt.OnuStatistics, 100)
98var gemStats = make(chan *openolt.GemPortStatistics, 100)
99
kesavand62126212021-01-12 04:56:06 -0500100//statRegInfo is used to register for notifications
101//on receiving port stats and flow stats indication
102type statRegInfo struct {
103 chn chan bool
104 portNo uint32
105 portType extension.GetOltPortCounters_PortType
106}
107
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108// PonPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530109type PonPort struct {
110 /*
111 This is a highly reduced version taken from the adtran pon_port.
112 TODO: Extend for use in the openolt adapter set.
113 */
114 /* MAX_ONUS_SUPPORTED = 256
115 DEFAULT_ENABLED = False
116 MAX_DEPLOYMENT_RANGE = 25000 # Meters (OLT-PB maximum)
117
118 _MCAST_ONU_ID = 253
119 _MCAST_ALLOC_BASE = 0x500
120
121 _SUPPORTED_ACTIVATION_METHODS = ['autodiscovery'] # , 'autoactivate']
122 _SUPPORTED_AUTHENTICATION_METHODS = ['serial-number']
123 */
124 PONID uint32
125 DeviceID string
126 IntfID uint32
127 PortNum uint32
128 PortID uint32
129 Label string
130 ONUs map[uint32]interface{}
131 ONUsByID map[uint32]interface{}
132
133 RxBytes uint64
134 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000135 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530136 RxMcastPackets uint64
137 RxBcastPackets uint64
138 RxErrorPackets uint64
139 TxBytes uint64
140 TxPackets uint64
141 TxUcastPackets uint64
142 TxMcastPackets uint64
143 TxBcastPackets uint64
144 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000145 RxCrcErrors uint64
146 BipErrors uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530147}
148
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700149// NewPONPort returns a new instance of PonPort initialized with given PONID, DeviceID, IntfID and PortNum
Abhilash S.L765ad002019-04-24 16:40:57 +0530150func NewPONPort(PONID uint32, DeviceID string, IntfID uint32, PortNum uint32) *PonPort {
151
152 var PON PonPort
153
154 PON.PONID = PONID
155 PON.DeviceID = DeviceID
156 PON.IntfID = IntfID
157 PON.PortNum = PortNum
158 PON.PortID = 0
Naga Manjunath7615e552019-10-11 22:35:47 +0530159 PON.Label = fmt.Sprintf("%s%d", "pon-", PONID)
Abhilash S.L765ad002019-04-24 16:40:57 +0530160
161 PON.ONUs = make(map[uint32]interface{})
162 PON.ONUsByID = make(map[uint32]interface{})
163
164 /*
165 Statistics taken from nni_port
166 self.intf_id = 0 #handled by getter
167 self.port_no = 0 #handled by getter
168 self.port_id = 0 #handled by getter
169
170 Note: In the current implementation of the kpis coming from the BAL the stats are the
171 samne model for NNI and PON.
172
173 TODO: Integrate additional kpis for the PON and other southbound port objecgts.
174
175 */
176
177 PON.RxBytes = 0
178 PON.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000179 PON.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530180 PON.RxMcastPackets = 0
181 PON.RxBcastPackets = 0
182 PON.RxErrorPackets = 0
183 PON.TxBytes = 0
184 PON.TxPackets = 0
185 PON.TxUcastPackets = 0
186 PON.TxMcastPackets = 0
187 PON.TxBcastPackets = 0
188 PON.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000189 PON.RxCrcErrors = 0
190 PON.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530191
192 /* def __str__(self):
193 return "PonPort-{}: Admin: {}, Oper: {}, OLT: {}".format(self._label,
194 self._admin_state,
195 self._oper_status,
196 self.olt)
197 */
198 return &PON
199}
200
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700201// NniPort representation
Abhilash S.L765ad002019-04-24 16:40:57 +0530202type NniPort struct {
203 /*
204 Northbound network port, often Ethernet-based
205
206 This is a highly reduced version taken from the adtran nni_port code set
207 TODO: add functions to allow for port specific values and operations
208 */
209 PortNum uint32
210 Name string
211 LogicalPort uint32
212 IntfID uint32
213
214 RxBytes uint64
215 RxPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000216 RxUcastPackets uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530217 RxMcastPackets uint64
218 RxBcastPackets uint64
219 RxErrorPackets uint64
220 TxBytes uint64
221 TxPackets uint64
222 TxUcastPackets uint64
223 TxMcastPackets uint64
224 TxBcastPackets uint64
225 TxErrorPackets uint64
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000226 RxCrcErrors uint64
227 BipErrors uint64
Abhilash S.L765ad002019-04-24 16:40:57 +0530228}
229
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700230// NewNniPort returns a new instance of NniPort initialized with the given PortNum and IntfID
Abhilash S.L765ad002019-04-24 16:40:57 +0530231func NewNniPort(PortNum uint32, IntfID uint32) *NniPort {
232
233 var NNI NniPort
234
235 NNI.PortNum = PortNum
Naga Manjunath7615e552019-10-11 22:35:47 +0530236 NNI.Name = fmt.Sprintf("%s%d", "nni-", PortNum)
Abhilash S.L765ad002019-04-24 16:40:57 +0530237 NNI.IntfID = IntfID
238
239 NNI.RxBytes = 0
240 NNI.RxPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000241 NNI.RxUcastPackets = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530242 NNI.RxMcastPackets = 0
243 NNI.RxBcastPackets = 0
244 NNI.RxErrorPackets = 0
245 NNI.TxBytes = 0
246 NNI.TxPackets = 0
247 NNI.TxUcastPackets = 0
248 NNI.TxMcastPackets = 0
249 NNI.TxBcastPackets = 0
250 NNI.TxErrorPackets = 0
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000251 NNI.RxCrcErrors = 0
252 NNI.BipErrors = 0
Abhilash S.L765ad002019-04-24 16:40:57 +0530253
254 return &NNI
255}
256
kesavand62126212021-01-12 04:56:06 -0500257//StatType defines portStatsType and flowStatsType types
258type StatType int
259
260const (
261 portStatsType StatType = iota
262 flowStatsType
263)
264
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700265// OpenOltStatisticsMgr structure
Abhilash S.L765ad002019-04-24 16:40:57 +0530266type OpenOltStatisticsMgr struct {
267 Device *DeviceHandler
Naga Manjunath7615e552019-10-11 22:35:47 +0530268 NorthBoundPort map[uint32]*NniPort
269 SouthBoundPort map[uint32]*PonPort
Abhilash S.L765ad002019-04-24 16:40:57 +0530270 // TODO PMMetrics Metrics
kesavand62126212021-01-12 04:56:06 -0500271 //statIndListners is the list of requests to be notified when port and flow stats indication is received
272 statIndListnerMu sync.Mutex
273 statIndListners map[StatType]*list.List
Abhilash S.L765ad002019-04-24 16:40:57 +0530274}
275
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700276// NewOpenOltStatsMgr returns a new instance of the OpenOltStatisticsMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000277func NewOpenOltStatsMgr(ctx context.Context, Dev *DeviceHandler) *OpenOltStatisticsMgr {
Abhilash S.L765ad002019-04-24 16:40:57 +0530278
279 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)
288 NumPonPorts := Dev.resourceMgr.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)
Naga Manjunath7615e552019-10-11 22:35:47 +0530328 PONPorts[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
348 //This builds a port object which is added to the
349 //appropriate northbound or southbound values
350 if IntfType == "nni" {
Naga Manjunath7615e552019-10-11 22:35:47 +0530351 IntfID := IntfIDToPortNo(PortNum, voltha.Port_ETHERNET_NNI)
352 nniID := 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.
Naga Manjunath7615e552019-10-11 22:35:47 +0530361 IntfID := IntfIDToPortNo(PortNum, voltha.Port_PON_OLT)
362 PONID := 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 {
376
377 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 {
417
418 ponval := make(map[string]float32)
419 mutex.Lock()
420 cm := StatMgr.Device.portStats.SouthBoundPort[pID]
421 mutex.Unlock()
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000422 metricNames := StatMgr.Device.metrics.GetSubscriberMetrics()
Naga Manjunath7615e552019-10-11 22:35:47 +0530423
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000424 var metrics []string
Kent Hagermane6ff1012020-07-14 15:07:53 -0400425 for metric := range metricNames {
426 if metricNames[metric].Enabled {
427 metrics = append(metrics, metric)
Naga Manjunath7615e552019-10-11 22:35:47 +0530428 }
429 }
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000430
431 for _, mName := range metrics {
432 switch mName {
433 case "rx_bytes":
434 ponval["RxBytes"] = float32(cm.RxBytes)
435 case "rx_packets":
436 ponval["RxPackets"] = float32(cm.RxPackets)
437 case "rx_ucast_packets":
438 ponval["RxUcastPackets"] = float32(cm.RxUcastPackets)
439 case "rx_mcast_packets":
440 ponval["RxMcastPackets"] = float32(cm.RxMcastPackets)
441 case "rx_bcast_packets":
442 ponval["RxBcastPackets"] = float32(cm.RxBcastPackets)
443 case "tx_bytes":
444 ponval["TxBytes"] = float32(cm.TxBytes)
445 case "tx_packets":
446 ponval["TxPackets"] = float32(cm.TxPackets)
447 case "tx_mcast_packets":
448 ponval["TxMcastPackets"] = float32(cm.TxMcastPackets)
449 case "tx_bcast_packets":
450 ponval["TxBcastPackets"] = float32(cm.TxBcastPackets)
451 }
452 }
453
Naga Manjunath7615e552019-10-11 22:35:47 +0530454 return ponval
455}
456
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000457// converGemStats will convert gem stats response to kpi context
458func (StatMgr *OpenOltStatisticsMgr) convertGemStats(gemStats *openolt.GemPortStatistics) map[string]float32 {
459 gemStatsVal := make(map[string]float32)
460 gemStatsVal[IntfID] = float32(gemStats.IntfId)
461 gemStatsVal[GemID] = float32(gemStats.GemportId)
462 gemStatsVal[RxPackets] = float32(gemStats.RxPackets)
463 gemStatsVal[RxBytes] = float32(gemStats.RxBytes)
464 gemStatsVal[TxPackets] = float32(gemStats.TxPackets)
465 gemStatsVal[TxBytes] = float32(gemStats.TxBytes)
466 return gemStatsVal
467}
468
469// convertONUStats will convert onu stats response to kpi context
470func (StatMgr *OpenOltStatisticsMgr) convertONUStats(onuStats *openolt.OnuStatistics) map[string]float32 {
471 onuStatsVal := make(map[string]float32)
472 onuStatsVal[IntfID] = float32(onuStats.IntfId)
473 onuStatsVal[OnuID] = float32(onuStats.OnuId)
474 onuStatsVal[PositiveDrift] = float32(onuStats.PositiveDrift)
475 onuStatsVal[NegativeDrift] = float32(onuStats.NegativeDrift)
476 onuStatsVal[DelimiterMissDetection] = float32(onuStats.DelimiterMissDetection)
477 onuStatsVal[BipErrors] = float32(onuStats.BipErrors)
478 onuStatsVal[BipUnits] = float32(onuStats.BipUnits)
479 onuStatsVal[FecCorrectedSymbols] = float32(onuStats.FecCorrectedSymbols)
480 onuStatsVal[FecCodewordsCorrected] = float32(onuStats.FecCodewordsCorrected)
481 onuStatsVal[fecCodewordsUncorrectable] = float32(onuStats.FecCodewordsUncorrectable)
482 onuStatsVal[FecCodewords] = float32(onuStats.FecCodewords)
483 onuStatsVal[FecCorrectedUnits] = float32(onuStats.FecCorrectedUnits)
484 onuStatsVal[XGEMKeyErrors] = float32(onuStats.XgemKeyErrors)
485 onuStatsVal[XGEMLoss] = float32(onuStats.XgemLoss)
486 onuStatsVal[RxPloamsError] = float32(onuStats.RxPloamsError)
487 onuStatsVal[RxPloamsNonIdle] = float32(onuStats.RxPloamsNonIdle)
488 onuStatsVal[RxOmci] = float32(onuStats.RxOmci)
489 onuStatsVal[RxOmciPacketsCrcError] = float32(onuStats.RxOmciPacketsCrcError)
490 onuStatsVal[RxBytes] = float32(onuStats.RxBytes)
491 onuStatsVal[RxPackets] = float32(onuStats.RxPackets)
492 onuStatsVal[TxBytes] = float32(onuStats.TxBytes)
493 onuStatsVal[TxPackets] = float32(onuStats.TxPackets)
494 onuStatsVal[BerReported] = float32(onuStats.BerReported)
495 onuStatsVal[LcdgErrors] = float32(onuStats.LcdgErrors)
496 onuStatsVal[RdiErrors] = float32(onuStats.RdiErrors)
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530497 onuStatsVal[Timestamp] = float32(onuStats.Timestamp)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000498 return onuStatsVal
499}
500
501// collectOnuStats will collect the onu metrics
502func (StatMgr *OpenOltStatisticsMgr) collectOnuStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
503 onu := &openolt.Onu{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID}
504 logger.Debugw(ctx, "pulling-onu-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID})
505 if stats, err := StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
506 onuStats <- stats
507 } else {
508 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "err": err})
509 }
510}
511
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530512// collectOnDemandOnuStats will collect the onui-pon metrics
513func (StatMgr *OpenOltStatisticsMgr) collectOnDemandOnuStats(ctx context.Context, intfID uint32, onuID uint32) map[string]float32 {
514 onu := &openolt.Onu{IntfId: intfID, OnuId: onuID}
515 var stats *openolt.OnuStatistics
516 var err error
517 logger.Debugw(ctx, "pulling-onu-stats-on-demand", log.Fields{"IntfID": intfID, "OnuID": onuID})
518 if stats, err = StatMgr.Device.Client.GetOnuStatistics(context.Background(), onu); err == nil {
519 statValue := StatMgr.convertONUStats(stats)
520 return statValue
521
522 }
523 logger.Errorw(ctx, "error-while-getting-onu-stats-for-onu", log.Fields{"IntfID": intfID, "OnuID": onuID, "err": err})
524 return nil
525}
526
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000527// collectOnuAndGemStats will collect both onu and gem metrics
528func (StatMgr *OpenOltStatisticsMgr) collectOnuAndGemStats(ctx context.Context, onuGemInfo []rsrcMgr.OnuGemInfo) {
529 if !StatMgr.Device.openOLT.enableONUStats && !StatMgr.Device.openOLT.enableGemStats {
530 return
531 }
532
533 for _, onuInfo := range onuGemInfo {
534 if StatMgr.Device.openOLT.enableONUStats {
535 go StatMgr.collectOnuStats(ctx, onuInfo)
536 }
537 if StatMgr.Device.openOLT.enableGemStats {
538 go StatMgr.collectGemStats(ctx, onuInfo)
539 }
540 }
541}
542
543// collectGemStats will collect gem metrics
544func (StatMgr *OpenOltStatisticsMgr) collectGemStats(ctx context.Context, onuGemInfo rsrcMgr.OnuGemInfo) {
545 for _, gem := range onuGemInfo.GemPorts {
546 logger.Debugw(ctx, "pulling-gem-stats", log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem})
547 onuPacket := &openolt.OnuPacket{IntfId: onuGemInfo.IntfID, OnuId: onuGemInfo.OnuID, GemportId: gem}
548 if stats, err := StatMgr.Device.Client.GetGemPortStatistics(context.Background(), onuPacket); err == nil {
549 gemStats <- stats
550 } else {
551 logger.Errorw(ctx, "error-while-getting-gem-stats-for-onu",
552 log.Fields{"IntfID": onuGemInfo.IntfID, "OnuID": onuGemInfo.OnuID, "GemID": gem, "err": err})
553 }
554 }
555}
556
557// publishGemStats will publish the gem metrics
558func (StatMgr *OpenOltStatisticsMgr) publishGemStats() {
559 for {
560 statValue := StatMgr.convertGemStats(<-gemStats)
561 StatMgr.publishMetrics(context.Background(), GEMStats, statValue, &voltha.Port{Label: "GEM"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
562 }
563}
564
565// publishOnuStats will publish the onu metrics
566func (StatMgr *OpenOltStatisticsMgr) publishOnuStats() {
567 for {
568 statValue := StatMgr.convertONUStats(<-onuStats)
569 StatMgr.publishMetrics(context.Background(), ONUStats, statValue, &voltha.Port{Label: "ONU"}, StatMgr.Device.device.Id, StatMgr.Device.device.Type)
570 }
571}
572
573// publishMetrics will publish the pon port metrics
kesavand62126212021-01-12 04:56:06 -0500574func (StatMgr *OpenOltStatisticsMgr) publishMetrics(ctx context.Context, statType string, val map[string]float32,
Girish Gowdra34815db2020-05-11 17:18:04 -0700575 port *voltha.Port, devID string, devType string) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000576 logger.Debugw(ctx, "publish-metrics",
Shrey Baid26912972020-04-16 21:02:31 +0530577 log.Fields{
578 "port": port.Label,
579 "metrics": val})
Naga Manjunath7615e552019-10-11 22:35:47 +0530580
581 var metricInfo voltha.MetricInformation
582 var ke voltha.KpiEvent2
Esin Karamanccb714b2019-11-29 15:02:06 +0000583 var volthaEventSubCatgry voltha.EventSubCategory_Types
Girish Gowdra34815db2020-05-11 17:18:04 -0700584 metricsContext := make(map[string]string)
585 metricsContext["oltid"] = devID
586 metricsContext["devicetype"] = devType
587 metricsContext["portlabel"] = port.Label
Naga Manjunath7615e552019-10-11 22:35:47 +0530588
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000589 if statType == NNIStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530590 volthaEventSubCatgry = voltha.EventSubCategory_NNI
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000591 } else if statType == PONStats {
Naga Manjunath7615e552019-10-11 22:35:47 +0530592 volthaEventSubCatgry = voltha.EventSubCategory_PON
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000593 } else if statType == GEMStats || statType == ONUStats {
594 volthaEventSubCatgry = voltha.EventSubCategory_ONT
Naga Manjunath7615e552019-10-11 22:35:47 +0530595 }
596
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700597 raisedTs := time.Now().Unix()
Naga Manjunath7615e552019-10-11 22:35:47 +0530598 mmd := voltha.MetricMetaData{
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000599 Title: statType,
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700600 Ts: float64(raisedTs),
Girish Gowdra34815db2020-05-11 17:18:04 -0700601 Context: metricsContext,
Naga Manjunath7615e552019-10-11 22:35:47 +0530602 DeviceId: devID,
603 }
604
605 metricInfo.Metadata = &mmd
606 metricInfo.Metrics = val
607
608 ke.SliceData = []*voltha.MetricInformation{&metricInfo}
609 ke.Type = voltha.KpiEventType_slice
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700610 ke.Ts = float64(raisedTs)
Naga Manjunath7615e552019-10-11 22:35:47 +0530611
Neha Sharma96b7bf22020-06-15 10:37:32 +0000612 if err := StatMgr.Device.EventProxy.SendKpiEvent(ctx, "STATS_EVENT", &ke, voltha.EventCategory_EQUIPMENT, volthaEventSubCatgry, raisedTs); err != nil {
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000613 logger.Errorw(ctx, "failed-to-send-stats", log.Fields{"err": err})
Naga Manjunath7615e552019-10-11 22:35:47 +0530614 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530615}
616
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700617// PortStatisticsIndication handles the port statistics indication
Neha Sharma96b7bf22020-06-15 10:37:32 +0000618func (StatMgr *OpenOltStatisticsMgr) PortStatisticsIndication(ctx context.Context, PortStats *openolt.PortStatistics, NumPonPorts uint32) {
619 StatMgr.PortsStatisticsKpis(ctx, PortStats, NumPonPorts)
620 logger.Debugw(ctx, "received-port-stats-indication", log.Fields{"port-stats": PortStats})
kesavand62126212021-01-12 04:56:06 -0500621 //Indicate that PortStatisticsIndication is handled
622 //PortStats.IntfId is actually the port number
623 StatMgr.processStatIndication(ctx, portStatsType, PortStats.IntfId)
Abhilash S.L765ad002019-04-24 16:40:57 +0530624 // TODO send stats to core topic to the voltha kafka or a different kafka ?
625}
626
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700627// FlowStatisticsIndication to be implemented
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628func FlowStatisticsIndication(ctx context.Context, self, FlowStats *openolt.FlowStatistics) {
629 logger.Debugw(ctx, "flow-stats-collected", log.Fields{"flow-stats": FlowStats})
Abhilash S.L765ad002019-04-24 16:40:57 +0530630 //TODO send to kafka ?
631}
632
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700633// PortsStatisticsKpis map the port stats values into a dictionary, creates the kpiEvent and then publish to Kafka
Neha Sharma96b7bf22020-06-15 10:37:32 +0000634func (StatMgr *OpenOltStatisticsMgr) PortsStatisticsKpis(ctx context.Context, PortStats *openolt.PortStatistics, NumPonPorts uint32) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530635
636 /*map the port stats values into a dictionary
637 Create a kpoEvent and publish to Kafka
638
639 :param port_stats:
640 :return:
641 */
642 //var err error
643 IntfID := PortStats.IntfId
644
Naga Manjunath7615e552019-10-11 22:35:47 +0530645 if (IntfIDToPortNo(1, voltha.Port_ETHERNET_NNI) < IntfID) &&
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700646 (IntfID < IntfIDToPortNo(4, voltha.Port_ETHERNET_NNI)) {
Abhilash S.L765ad002019-04-24 16:40:57 +0530647 /*
648 for this release we are only interested in the first NNI for
649 Northbound.
650 we are not using the other 3
651 */
652 return
Naga Manjunath7615e552019-10-11 22:35:47 +0530653 } else if IntfIDToPortNo(0, voltha.Port_ETHERNET_NNI) == IntfID {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700654
Naga Manjunath7615e552019-10-11 22:35:47 +0530655 var portNNIStat NniPort
656 portNNIStat.IntfID = IntfID
657 portNNIStat.PortNum = uint32(0)
658 portNNIStat.RxBytes = PortStats.RxBytes
659 portNNIStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000660 portNNIStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530661 portNNIStat.RxMcastPackets = PortStats.RxMcastPackets
662 portNNIStat.RxBcastPackets = PortStats.RxBcastPackets
663 portNNIStat.TxBytes = PortStats.TxBytes
664 portNNIStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000665 portNNIStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530666 portNNIStat.TxMcastPackets = PortStats.TxMcastPackets
667 portNNIStat.TxBcastPackets = PortStats.TxBcastPackets
668 mutex.Lock()
669 StatMgr.NorthBoundPort[0] = &portNNIStat
670 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000671 logger.Debugw(ctx, "received-nni-stats", log.Fields{"nni-stats": StatMgr.NorthBoundPort})
Naga Manjunath7615e552019-10-11 22:35:47 +0530672 }
673 for i := uint32(0); i < NumPonPorts; i++ {
674
675 if IntfIDToPortNo(i, voltha.Port_PON_OLT) == IntfID {
676 var portPonStat PonPort
677 portPonStat.IntfID = IntfID
678 portPonStat.PortNum = i
679 portPonStat.PONID = i
680 portPonStat.RxBytes = PortStats.RxBytes
681 portPonStat.RxPackets = PortStats.RxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000682 portPonStat.RxUcastPackets = PortStats.RxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530683 portPonStat.RxMcastPackets = PortStats.RxMcastPackets
684 portPonStat.RxBcastPackets = PortStats.RxBcastPackets
685 portPonStat.TxBytes = PortStats.TxBytes
686 portPonStat.TxPackets = PortStats.TxPackets
Dileep Kuchhangi52cfbe12020-01-15 20:16:21 +0000687 portPonStat.TxUcastPackets = PortStats.TxUcastPackets
Naga Manjunath7615e552019-10-11 22:35:47 +0530688 portPonStat.TxMcastPackets = PortStats.TxMcastPackets
689 portPonStat.TxBcastPackets = PortStats.TxBcastPackets
690 mutex.Lock()
691 StatMgr.SouthBoundPort[i] = &portPonStat
692 mutex.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000693 logger.Debugw(ctx, "received-pon-stats-for-port", log.Fields{"port-pon-stats": portPonStat})
Naga Manjunath7615e552019-10-11 22:35:47 +0530694 }
695 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700696
697 /*
698 Based upon the intf_id map to an nni port or a pon port
699 the intf_id is the key to the north or south bound collections
700
701 Based upon the intf_id the port object (nni_port or pon_port) will
702 have its data attr. updated by the current dataset collected.
703
704 For prefixing the rule is currently to use the port number and not the intf_id
705 */
706 //FIXME : Just use first NNI for now
707 /* TODO should the data be marshaled before sending it ?
708 if IntfID == IntfIdToPortNo(0, voltha.Port_ETHERNET_NNI) {
709 //NNI port (just the first one)
710 err = UpdatePortObjectKpiData(StatMgr.NorthBoundPorts[PortStats.IntfID], PMData)
711 } else {
712 //PON ports
713 err = UpdatePortObjectKpiData(SouthboundPorts[PortStats.IntfID], PMData)
714 }
715 if (err != nil) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000716 logger.Error(ctx, "Error publishing statistics data")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700717 }
718 */
719
Abhilash S.L765ad002019-04-24 16:40:57 +0530720}
kesavand62126212021-01-12 04:56:06 -0500721
722func (StatMgr *OpenOltStatisticsMgr) updateGetOltPortCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
723
724 metrics := singleValResp.GetResponse().GetPortCoutners()
725 metrics.TxBytes = uint64(stats["TxBytes"])
726 metrics.RxBytes = uint64(stats["RxBytes"])
727 metrics.TxPackets = uint64(stats["TxPackets"])
728 metrics.RxPackets = uint64(stats["RxPackets"])
729 metrics.TxErrorPackets = uint64(stats["TxErrorPackets"])
730 metrics.RxErrorPackets = uint64(stats["RxErrorPackets"])
731 metrics.TxBcastPackets = uint64(stats["TxBcastPackets"])
732 metrics.RxBcastPackets = uint64(stats["RxBcastPackets"])
733 metrics.TxUcastPackets = uint64(stats["TxUcastPackets"])
734 metrics.RxUcastPackets = uint64(stats["RxUcastPackets"])
735 metrics.TxMcastPackets = uint64(stats["TxMcastPackets"])
736 metrics.RxMcastPackets = uint64(stats["RxMcastPackets"])
737
738 singleValResp.Response.Status = extension.GetValueResponse_OK
739 logger.Debugw(ctx, "updateGetOltPortCountersResponse", log.Fields{"resp": singleValResp})
740}
741
742//RegisterForStatIndication registers ch as a channel on which indication is sent when statistics of type t is received
743func (StatMgr *OpenOltStatisticsMgr) RegisterForStatIndication(ctx context.Context, t StatType, ch chan bool, portNo uint32, portType extension.GetOltPortCounters_PortType) {
744 statInd := statRegInfo{
745 chn: ch,
746 portNo: portNo,
747 portType: portType,
748 }
749
750 logger.Debugf(ctx, "RegisterForStatIndication stat type %v portno %v porttype %v chan %v", t, portNo, portType, ch)
751 StatMgr.statIndListnerMu.Lock()
752 StatMgr.statIndListners[t].PushBack(statInd)
753 StatMgr.statIndListnerMu.Unlock()
754
755}
756
757//DeRegisterFromStatIndication removes the previously registered channel ch for type t of statistics
758func (StatMgr *OpenOltStatisticsMgr) DeRegisterFromStatIndication(ctx context.Context, t StatType, ch chan bool) {
759 StatMgr.statIndListnerMu.Lock()
760 defer StatMgr.statIndListnerMu.Unlock()
761
762 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
763 statInd := e.Value.(statRegInfo)
764 if statInd.chn == ch {
765 StatMgr.statIndListners[t].Remove(e)
766 return
767 }
768 }
769}
770
771func (StatMgr *OpenOltStatisticsMgr) processStatIndication(ctx context.Context, t StatType, portNo uint32) {
772 var deRegList []*list.Element
773 var statInd statRegInfo
774
775 StatMgr.statIndListnerMu.Lock()
776 defer StatMgr.statIndListnerMu.Unlock()
777
778 if StatMgr.statIndListners[t] == nil || StatMgr.statIndListners[t].Len() == 0 {
779 logger.Debugf(ctx, "processStatIndication %v list is empty ", t)
780 return
781 }
782
783 for e := StatMgr.statIndListners[t].Front(); e != nil; e = e.Next() {
784 statInd = e.Value.(statRegInfo)
785 if statInd.portNo != portNo {
786 fmt.Printf("Skipping %v\n", e.Value)
787 continue
788 }
789 // message sent
790 statInd.chn <- true
791 deRegList = append(deRegList, e)
792
793 }
794 for _, e := range deRegList {
795 StatMgr.statIndListners[t].Remove(e)
796 }
797
798}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +0530799
800func (StatMgr *OpenOltStatisticsMgr) updateGetOnuPonCountersResponse(ctx context.Context, singleValResp *extension.SingleGetValueResponse, stats map[string]float32) {
801
802 metrics := singleValResp.GetResponse().GetOnuPonCounters()
803 metrics.IsIntfId = &extension.GetOnuCountersResponse_IntfId{
804 IntfId: uint32(stats[IntfID]),
805 }
806 metrics.IsOnuId = &extension.GetOnuCountersResponse_OnuId{
807 OnuId: uint32(stats[OnuID]),
808 }
809 metrics.IsPositiveDrift = &extension.GetOnuCountersResponse_PositiveDrift{
810 PositiveDrift: uint64(stats[PositiveDrift]),
811 }
812 metrics.IsNegativeDrift = &extension.GetOnuCountersResponse_NegativeDrift{
813 NegativeDrift: uint64(stats[NegativeDrift]),
814 }
815 metrics.IsDelimiterMissDetection = &extension.GetOnuCountersResponse_DelimiterMissDetection{
816 DelimiterMissDetection: uint64(stats[DelimiterMissDetection]),
817 }
818 metrics.IsBipErrors = &extension.GetOnuCountersResponse_BipErrors{
819 BipErrors: uint64(stats[BipErrors]),
820 }
821 metrics.IsBipUnits = &extension.GetOnuCountersResponse_BipUnits{
822 BipUnits: uint64(stats[BipUnits]),
823 }
824 metrics.IsFecCorrectedSymbols = &extension.GetOnuCountersResponse_FecCorrectedSymbols{
825 FecCorrectedSymbols: uint64(stats[FecCorrectedSymbols]),
826 }
827 metrics.IsFecCodewordsCorrected = &extension.GetOnuCountersResponse_FecCodewordsCorrected{
828 FecCodewordsCorrected: uint64(stats[FecCodewordsCorrected]),
829 }
830 metrics.IsFecCodewordsUncorrectable = &extension.GetOnuCountersResponse_FecCodewordsUncorrectable{
831 FecCodewordsUncorrectable: uint64(stats[fecCodewordsUncorrectable]),
832 }
833 metrics.IsFecCodewords = &extension.GetOnuCountersResponse_FecCodewords{
834 FecCodewords: uint64(stats[FecCodewords]),
835 }
836 metrics.IsFecCorrectedUnits = &extension.GetOnuCountersResponse_FecCorrectedUnits{
837 FecCorrectedUnits: uint64(stats[FecCorrectedUnits]),
838 }
839 metrics.IsXgemKeyErrors = &extension.GetOnuCountersResponse_XgemKeyErrors{
840 XgemKeyErrors: uint64(stats[XGEMKeyErrors]),
841 }
842 metrics.IsXgemLoss = &extension.GetOnuCountersResponse_XgemLoss{
843 XgemLoss: uint64(stats[XGEMLoss]),
844 }
845 metrics.IsRxPloamsError = &extension.GetOnuCountersResponse_RxPloamsError{
846 RxPloamsError: uint64(stats[RxPloamsError]),
847 }
848 metrics.IsRxPloamsNonIdle = &extension.GetOnuCountersResponse_RxPloamsNonIdle{
849 RxPloamsNonIdle: uint64(stats[RxPloamsNonIdle]),
850 }
851 metrics.IsRxOmci = &extension.GetOnuCountersResponse_RxOmci{
852 RxOmci: uint64(stats[RxOmci]),
853 }
854 metrics.IsRxOmciPacketsCrcError = &extension.GetOnuCountersResponse_RxOmciPacketsCrcError{
855 RxOmciPacketsCrcError: uint64(stats[RxOmciPacketsCrcError]),
856 }
857 metrics.IsRxBytes = &extension.GetOnuCountersResponse_RxBytes{
858 RxBytes: uint64(stats[RxBytes]),
859 }
860 metrics.IsRxPackets = &extension.GetOnuCountersResponse_RxPackets{
861 RxPackets: uint64(stats[RxPackets]),
862 }
863 metrics.IsTxBytes = &extension.GetOnuCountersResponse_TxBytes{
864 TxBytes: uint64(stats[TxBytes]),
865 }
866 metrics.IsTxPackets = &extension.GetOnuCountersResponse_TxPackets{
867 TxPackets: uint64(stats[TxPackets]),
868 }
869 metrics.IsBerReported = &extension.GetOnuCountersResponse_BerReported{
870 BerReported: uint64(stats[BerReported]),
871 }
872 metrics.IsLcdgErrors = &extension.GetOnuCountersResponse_LcdgErrors{
873 LcdgErrors: uint64(stats[LcdgErrors]),
874 }
875 metrics.IsRdiErrors = &extension.GetOnuCountersResponse_RdiErrors{
876 RdiErrors: uint64(stats[RdiErrors]),
877 }
878 metrics.IsTimestamp = &extension.GetOnuCountersResponse_Timestamp{
879 Timestamp: uint32(stats[Timestamp]),
880 }
881
882 singleValResp.Response.Status = extension.GetValueResponse_OK
883 logger.Debugw(ctx, "updateGetOnuPonCountersResponse", log.Fields{"resp": singleValResp})
884}