blob: 67a65fffbe5ba2a79df8ce78f076bc1ef36a10b3 [file] [log] [blame]
Matteo Scandolof9d43412021-01-12 11:11:34 -08001/*
2 * Copyright 2018-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 */
16
17package omci
18
19import (
20 "encoding/hex"
21 "errors"
22 "fmt"
23 "github.com/google/gopacket"
24 "github.com/opencord/omci-lib-go"
25 me "github.com/opencord/omci-lib-go/generated"
Matteo Scandolo5863f002021-02-08 08:08:14 -080026 "github.com/opencord/voltha-protos/v4/go/openolt"
Matteo Scandolof9d43412021-01-12 11:11:34 -080027 log "github.com/sirupsen/logrus"
Girish Gowdraa539f522021-02-15 23:00:45 -080028 "math/rand"
Matteo Scandolof9d43412021-01-12 11:11:34 -080029 "strconv"
30)
31
32func ParseGetRequest(omciPkt gopacket.Packet) (*omci.GetRequest, error) {
33 msgLayer := omciPkt.Layer(omci.LayerTypeGetRequest)
34 if msgLayer == nil {
35 err := "omci Msg layer could not be detected for LayerTypeGetRequest"
36 omciLogger.Error(err)
37 return nil, errors.New(err)
38 }
39 msgObj, msgOk := msgLayer.(*omci.GetRequest)
40 if !msgOk {
41 err := "omci Msg layer could not be assigned for LayerTypeGetRequest"
42 omciLogger.Error(err)
43 return nil, errors.New(err)
44 }
45 return msgObj, nil
46}
47
Girish Gowdra996d81e2021-04-21 16:16:27 -070048func CreateGetResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI, onuSn *openolt.SerialNumber, mds uint8, activeImageEntityId uint16, committedImageEntityId uint16, onuDown bool) ([]byte, error) {
Matteo Scandolof9d43412021-01-12 11:11:34 -080049
50 msgObj, err := ParseGetRequest(omciPkt)
51
52 if err != nil {
53 return nil, err
54 }
55
56 omciLogger.WithFields(log.Fields{
57 "EntityClass": msgObj.EntityClass,
58 "EntityInstance": msgObj.EntityInstance,
59 "AttributeMask": fmt.Sprintf("%x", msgObj.AttributeMask),
Matteo Scandolo992a23e2021-02-04 15:35:04 -080060 }).Trace("received-omci-get-request")
Matteo Scandolof9d43412021-01-12 11:11:34 -080061
62 var response *omci.GetResponse
63 switch msgObj.EntityClass {
64 case me.Onu2GClassID:
65 response = createOnu2gResponse(msgObj.AttributeMask, msgObj.EntityInstance)
66 case me.OnuGClassID:
Matteo Scandolo5863f002021-02-08 08:08:14 -080067 response = createOnugResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuSn)
Matteo Scandolof9d43412021-01-12 11:11:34 -080068 case me.SoftwareImageClassID:
Matteo Scandolocedde462021-03-09 17:37:16 -080069 response = createSoftwareImageResponse(msgObj.AttributeMask, msgObj.EntityInstance, activeImageEntityId, committedImageEntityId)
Matteo Scandolof9d43412021-01-12 11:11:34 -080070 case me.IpHostConfigDataClassID:
71 response = createIpHostResponse(msgObj.AttributeMask, msgObj.EntityInstance)
72 case me.UniGClassID:
Girish Gowdra996d81e2021-04-21 16:16:27 -070073 response = createUnigResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
Matteo Scandolof9d43412021-01-12 11:11:34 -080074 case me.PhysicalPathTerminationPointEthernetUniClassID:
Girish Gowdra996d81e2021-04-21 16:16:27 -070075 response = createPptpResponse(msgObj.AttributeMask, msgObj.EntityInstance, onuDown)
Matteo Scandolof9d43412021-01-12 11:11:34 -080076 case me.AniGClassID:
77 response = createAnigResponse(msgObj.AttributeMask, msgObj.EntityInstance)
78 case me.OnuDataClassID:
Matteo Scandolo992a23e2021-02-04 15:35:04 -080079 response = createOnuDataResponse(msgObj.AttributeMask, msgObj.EntityInstance, mds)
Girish Gowdraa539f522021-02-15 23:00:45 -080080 case me.EthernetFramePerformanceMonitoringHistoryDataUpstreamClassID:
81 response = createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(msgObj.AttributeMask, msgObj.EntityInstance)
82 case me.EthernetFramePerformanceMonitoringHistoryDataDownstreamClassID:
83 response = createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(msgObj.AttributeMask, msgObj.EntityInstance)
84 case me.EthernetPerformanceMonitoringHistoryDataClassID:
85 response = createEthernetPerformanceMonitoringHistoryDataResponse(msgObj.AttributeMask, msgObj.EntityInstance)
Girish Gowdra6d9a1a42021-03-05 16:07:15 -080086 case me.FecPerformanceMonitoringHistoryDataClassID:
87 response = createFecPerformanceMonitoringHistoryDataResponse(msgObj.AttributeMask, msgObj.EntityInstance)
88 case me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID:
89 response = createGemPortNetworkCtpPerformanceMonitoringHistoryData(msgObj.AttributeMask, msgObj.EntityInstance)
Matteo Scandolof9d43412021-01-12 11:11:34 -080090 default:
91 omciLogger.WithFields(log.Fields{
92 "EntityClass": msgObj.EntityClass,
93 "EntityInstance": msgObj.EntityInstance,
94 "AttributeMask": fmt.Sprintf("%x", msgObj.AttributeMask),
95 }).Warnf("do-not-know-how-to-handle-get-request-for-me-class")
96 return nil, nil
97 }
98
Matteo Scandolo992a23e2021-02-04 15:35:04 -080099 pkt, err := Serialize(omci.GetResponseType, response, omciMsg.TransactionID)
Matteo Scandolof9d43412021-01-12 11:11:34 -0800100 if err != nil {
101 omciLogger.WithFields(log.Fields{
102 "Err": err,
103 "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800104 }).Error("cannot-Serialize-Onu2gResponse")
Matteo Scandolof9d43412021-01-12 11:11:34 -0800105 return nil, err
106 }
107
108 log.WithFields(log.Fields{
109 "TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
110 "pkt": hex.EncodeToString(pkt),
111 }).Trace("omci-get-response")
112
113 return pkt, nil
114}
115
116func createOnu2gResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
117
118 managedEntity, meErr := me.NewOnu2G(me.ParamData{
119 EntityID: entityID,
120 Attributes: me.AttributeValueMap{
121 "ManagedEntityId": entityID,
Matteo Scandolo9a1842d2021-02-08 16:00:17 -0800122 "EquipmentId": toOctets("12345123451234512345", 20),
Matteo Scandolof9d43412021-01-12 11:11:34 -0800123 "OpticalNetworkUnitManagementAndControlChannelOmccVersion": 180,
124 "VendorProductCode": 0,
125 "SecurityCapability": 1,
126 "SecurityMode": 1,
127 "TotalPriorityQueueNumber": 1,
128 "TotalTrafficSchedulerNumber": 1,
129 "Deprecated": 1,
130 "TotalGemPortIdNumber": 32,
131 "Sysuptime": 319389947, // NOTE need to be smarter?
132 "ConnectivityCapability": 127,
133 "CurrentConnectivityMode": 5,
134 "QualityOfServiceQosConfigurationFlexibility": 48,
135 "PriorityQueueScaleFactor": 1,
136 },
137 })
138
139 if meErr.GetError() != nil {
140 omciLogger.Errorf("NewOnu2G %v", meErr.Error())
141 return nil
142 }
143
144 return &omci.GetResponse{
145 MeBasePacket: omci.MeBasePacket{
146 EntityClass: me.Onu2GClassID,
147 },
148 Attributes: managedEntity.GetAttributeValueMap(),
149 AttributeMask: attributeMask,
150 Result: me.Success,
151 }
152}
153
Matteo Scandolo5863f002021-02-08 08:08:14 -0800154func createOnugResponse(attributeMask uint16, entityID uint16, onuSn *openolt.SerialNumber) *omci.GetResponse {
155
156 managedEntity, meErr := me.NewOnuG(me.ParamData{
157 EntityID: entityID,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800158 Attributes: me.AttributeValueMap{
159 "ManagedEntityId": entityID,
160 "VendorId": toOctets("BBSM", 4),
161 "Version": toOctets("v0.0.1", 14),
Matteo Scandolo5863f002021-02-08 08:08:14 -0800162 "SerialNumber": append(onuSn.VendorId, onuSn.VendorSpecific...),
Matteo Scandolof9d43412021-01-12 11:11:34 -0800163 "TrafficManagementOption": 0,
164 "Deprecated": 0,
165 "BatteryBackup": 0,
166 "AdministrativeState": 0,
167 "OperationalState": 0,
168 "OnuSurvivalTime": 10,
169 "LogicalOnuId": toOctets("BBSM", 24),
170 "LogicalPassword": toOctets("BBSM", 12),
171 "CredentialsStatus": 0,
172 "ExtendedTcLayerOptions": 0,
173 },
Matteo Scandolo5863f002021-02-08 08:08:14 -0800174 })
175
176 if meErr.GetError() != nil {
177 omciLogger.Errorf("NewOnu2G %v", meErr.Error())
178 return nil
Matteo Scandolof9d43412021-01-12 11:11:34 -0800179 }
Matteo Scandolo5863f002021-02-08 08:08:14 -0800180
181 return &omci.GetResponse{
182 MeBasePacket: omci.MeBasePacket{
183 EntityClass: me.OnuGClassID,
184 },
185 Attributes: managedEntity.GetAttributeValueMap(),
186 AttributeMask: attributeMask,
187 Result: me.Success,
188 }
189
190 //return &omci.GetResponse{
191 // MeBasePacket: omci.MeBasePacket{
192 // EntityClass: me.OnuGClassID,
193 // EntityInstance: entityID,
194 // },
195 // Attributes: me.AttributeValueMap{
196 //
197 // },
198 // Result: me.Success,
199 // AttributeMask: attributeMask,
200 //}
Matteo Scandolof9d43412021-01-12 11:11:34 -0800201}
202
Matteo Scandolocedde462021-03-09 17:37:16 -0800203func createSoftwareImageResponse(attributeMask uint16, entityInstance uint16, activeImageEntityId uint16, committedImageEntityId uint16) *omci.GetResponse {
204
205 omciLogger.WithFields(log.Fields{
206 "EntityInstance": entityInstance,
Matteo Scandolo21195d62021-04-07 14:31:23 -0700207 }).Trace("received-get-software-image-request")
Matteo Scandolocedde462021-03-09 17:37:16 -0800208
209 // Only one image can be active and committed
210 committed := 0
211 active := 0
212 if entityInstance == activeImageEntityId {
213 active = 1
214 }
215 if entityInstance == committedImageEntityId {
216 committed = 1
217 }
218
Matteo Scandolof9d43412021-01-12 11:11:34 -0800219 // NOTE that we need send the response for the correct ME Instance or the adapter won't process it
Matteo Scandolocedde462021-03-09 17:37:16 -0800220 res := &omci.GetResponse{
Matteo Scandolof9d43412021-01-12 11:11:34 -0800221 MeBasePacket: omci.MeBasePacket{
222 EntityClass: me.SoftwareImageClassID,
223 EntityInstance: entityInstance,
224 },
225 Attributes: me.AttributeValueMap{
226 "ManagedEntityId": 0,
Matteo Scandolo9a1842d2021-02-08 16:00:17 -0800227 "Version": toOctets("00000000000001", 14),
Matteo Scandolocedde462021-03-09 17:37:16 -0800228 "IsCommitted": committed,
229 "IsActive": active,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800230 "IsValid": 1,
231 "ProductCode": toOctets("product-code", 25),
232 "ImageHash": toOctets("broadband-sim", 16),
233 },
234 Result: me.Success,
235 AttributeMask: attributeMask,
236 }
Matteo Scandolocedde462021-03-09 17:37:16 -0800237
238 omciLogger.WithFields(log.Fields{
239 "omciMessage": res,
240 "entityId": entityInstance,
241 "active": active,
242 "committed": committed,
Matteo Scandolo21195d62021-04-07 14:31:23 -0700243 }).Trace("Reporting SoftwareImage")
Matteo Scandolocedde462021-03-09 17:37:16 -0800244
245 return res
Matteo Scandolof9d43412021-01-12 11:11:34 -0800246}
247
248func createIpHostResponse(attributeMask uint16, entityInstance uint16) *omci.GetResponse {
249 return &omci.GetResponse{
250 MeBasePacket: omci.MeBasePacket{
251 EntityClass: me.IpHostConfigDataClassID,
252 EntityInstance: entityInstance,
253 },
254 Attributes: me.AttributeValueMap{
255 "ManagedEntityId": 0,
256 "MacAddress": toOctets("aabbcc", 6),
257 },
258 Result: me.Success,
259 AttributeMask: attributeMask,
260 }
261}
262
Girish Gowdra996d81e2021-04-21 16:16:27 -0700263func createUnigResponse(attributeMask uint16, entityID uint16, onuDown bool) *omci.GetResponse {
264 // Valid values for uni_admin_state are 0 (unlocks) and 1 (locks)
265 omciAdminState := 1
266 if !onuDown {
267 omciAdminState = 0
268 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800269 managedEntity, meErr := me.NewUniG(me.ParamData{
270 EntityID: entityID,
271 Attributes: me.AttributeValueMap{
272 "ManagedEntityId": entityID,
273 "Deprecated": 0,
Girish Gowdra996d81e2021-04-21 16:16:27 -0700274 "AdministrativeState": omciAdminState,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800275 "ManagementCapability": 0,
276 "NonOmciManagementIdentifier": 1,
277 "RelayAgentOptions": 1,
278 },
279 })
280
281 if meErr.GetError() != nil {
282 omciLogger.Errorf("NewUniG %v", meErr.Error())
283 return nil
284 }
285
286 return &omci.GetResponse{
287 MeBasePacket: omci.MeBasePacket{
Girish Gowdrac3fd50c2021-03-12 16:14:44 -0800288 EntityClass: me.UniGClassID,
289 EntityInstance: entityID,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800290 },
291 Attributes: managedEntity.GetAttributeValueMap(),
292 AttributeMask: attributeMask,
293 Result: me.Success,
294 }
295}
296
Girish Gowdra996d81e2021-04-21 16:16:27 -0700297func createPptpResponse(attributeMask uint16, entityID uint16, onuDown bool) *omci.GetResponse {
298 // Valid values for oper_state are 0 (enabled) and 1 (disabled)
299 // Valid values for uni_admin_state are 0 (unlocks) and 1 (locks)
300 onuAdminState := 1
301 if !onuDown {
302 onuAdminState = 0
303 }
304 onuOperState := onuAdminState // For now make the assumption that oper state reflects the admin state
Matteo Scandolof9d43412021-01-12 11:11:34 -0800305 managedEntity, meErr := me.NewPhysicalPathTerminationPointEthernetUni(me.ParamData{
306 EntityID: entityID,
307 Attributes: me.AttributeValueMap{
308 "ManagedEntityId": entityID,
309 "ExpectedType": 0,
310 "SensedType": 0,
311 "AutoDetectionConfiguration": 0,
312 "EthernetLoopbackConfiguration": 0,
Girish Gowdra996d81e2021-04-21 16:16:27 -0700313 "AdministrativeState": onuAdminState,
314 "OperationalState": onuOperState,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800315 "ConfigurationInd": 0,
316 "MaxFrameSize": 0,
317 "DteOrDceInd": 0,
318 "PauseTime": 0,
319 "BridgedOrIpInd": 0,
320 "Arc": 0,
321 "ArcInterval": 0,
322 "PppoeFilter": 0,
323 "PowerControl": 0,
324 },
325 })
326
327 if meErr.GetError() != nil {
328 omciLogger.Errorf("NewPhysicalPathTerminationPointEthernetUni %v", meErr.Error())
329 return nil
330 }
331
332 return &omci.GetResponse{
333 MeBasePacket: omci.MeBasePacket{
Girish Gowdrac3fd50c2021-03-12 16:14:44 -0800334 EntityClass: me.PhysicalPathTerminationPointEthernetUniClassID,
335 EntityInstance: entityID,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800336 },
337 Attributes: managedEntity.GetAttributeValueMap(),
338 AttributeMask: attributeMask,
339 Result: me.Success,
340 }
341}
342
Girish Gowdraa539f522021-02-15 23:00:45 -0800343func createEthernetFramePerformanceMonitoringHistoryDataUpstreamResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
Girish Gowdraa539f522021-02-15 23:00:45 -0800344 managedEntity, meErr := me.NewEthernetFramePerformanceMonitoringHistoryDataUpstream(me.ParamData{
Matteo Scandolof9d43412021-01-12 11:11:34 -0800345 EntityID: entityID,
346 Attributes: me.AttributeValueMap{
Girish Gowdraa539f522021-02-15 23:00:45 -0800347 "ManagedEntityId": entityID,
348 "IntervalEndTime": 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
349 "ThresholdData12Id": 0,
350 "DropEvents": rand.Intn(100),
351 "Octets": rand.Intn(100),
352 "Packets": rand.Intn(100),
353 "BroadcastPackets": rand.Intn(100),
354 "MulticastPackets": rand.Intn(100),
355 "CrcErroredPackets": rand.Intn(100),
356 "UndersizePackets": rand.Intn(100),
357 "OversizePackets": rand.Intn(100),
358 "Packets64Octets": rand.Intn(100),
359 "Packets65To127Octets": rand.Intn(100),
360 "Packets128To255Octets": rand.Intn(100),
361 "Packets256To511Octets": rand.Intn(100),
362 "Packets512To1023Octets": rand.Intn(100),
363 "Packets1024To1518Octets": rand.Intn(100),
Matteo Scandolof9d43412021-01-12 11:11:34 -0800364 },
365 })
366
367 if meErr.GetError() != nil {
Girish Gowdraa539f522021-02-15 23:00:45 -0800368 omciLogger.Errorf("NewEthernetFramePerformanceMonitoringHistoryDataUpstream %v", meErr.Error())
Matteo Scandolof9d43412021-01-12 11:11:34 -0800369 return nil
370 }
371
Girish Gowdraa539f522021-02-15 23:00:45 -0800372 // L2 PM counters MEs exceed max allowed OMCI payload size.
373 // So the request/responses are always multipart.
374 // First identify the attributes that are not requested in the current GET request.
375 // Then filter out those attributes from the responses in the current GET response.
376 unwantedAttributeMask := ^attributeMask
377 var i uint16
378 for i = 1; i <= 16; i++ { // 1 and 16 because they are allowed valid min and max index keys in AttributeValueMap.
379 // We leave out 0 because that is ManagedEntity and that is a default IE in the map
380 if (1<<(16-i))&unwantedAttributeMask > 0 {
381 if err := managedEntity.DeleteAttributeByIndex(uint(i)); err != nil {
382 omciLogger.Errorf("error deleting attribute at index=%v, err=%v", i, err)
383 }
384 }
385 }
386
Matteo Scandolof9d43412021-01-12 11:11:34 -0800387 return &omci.GetResponse{
388 MeBasePacket: omci.MeBasePacket{
Girish Gowdraa539f522021-02-15 23:00:45 -0800389 EntityClass: me.EthernetFramePerformanceMonitoringHistoryDataUpstreamClassID,
390 EntityInstance: entityID,
391 },
392 Attributes: managedEntity.GetAttributeValueMap(),
393 AttributeMask: attributeMask,
394 Result: me.Success,
395 }
396}
397
398func createEthernetFramePerformanceMonitoringHistoryDataDownstreamResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
Girish Gowdraa539f522021-02-15 23:00:45 -0800399 managedEntity, meErr := me.NewEthernetFramePerformanceMonitoringHistoryDataDownstream(me.ParamData{
400 EntityID: entityID,
401 Attributes: me.AttributeValueMap{
402 "ManagedEntityId": entityID,
403 "IntervalEndTime": 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
404 "ThresholdData12Id": 0,
405 "DropEvents": rand.Intn(100),
406 "Octets": rand.Intn(100),
407 "Packets": rand.Intn(100),
408 "BroadcastPackets": rand.Intn(100),
409 "MulticastPackets": rand.Intn(100),
410 "CrcErroredPackets": rand.Intn(100),
411 "UndersizePackets": rand.Intn(100),
412 "OversizePackets": rand.Intn(100),
413 "Packets64Octets": rand.Intn(100),
414 "Packets65To127Octets": rand.Intn(100),
415 "Packets128To255Octets": rand.Intn(100),
416 "Packets256To511Octets": rand.Intn(100),
417 "Packets512To1023Octets": rand.Intn(100),
418 "Packets1024To1518Octets": rand.Intn(100),
419 },
420 })
421
422 if meErr.GetError() != nil {
423 omciLogger.Errorf("NewEthernetFramePerformanceMonitoringHistoryDataDownstream %v", meErr.Error())
424 return nil
425 }
426
427 // L2 PM counters MEs exceed max allowed OMCI payload size.
428 // So the request/responses are always multipart.
429 // First identify the attributes that are not requested in the current GET request.
430 // Then filter out those attributes from the responses in the current GET response.
431 unwantedAttributeMask := ^attributeMask
432 var i uint16
433 for i = 1; i <= 16; i++ { // 1 and 16 because they are allowed valid min and max index keys in AttributeValueMap.
434 // We leave out 0 because that is ManagedEntity and that is a default IE in the map
435 if (1<<(16-i))&unwantedAttributeMask > 0 {
436 if err := managedEntity.DeleteAttributeByIndex(uint(i)); err != nil {
437 omciLogger.Errorf("error deleting attribute at index=%v, err=%v", i, err)
438 }
439 }
440 }
441
442 return &omci.GetResponse{
443 MeBasePacket: omci.MeBasePacket{
444 EntityClass: me.EthernetFramePerformanceMonitoringHistoryDataDownstreamClassID,
445 EntityInstance: entityID,
446 },
447 Attributes: managedEntity.GetAttributeValueMap(),
448 AttributeMask: attributeMask,
449 Result: me.Success,
450 }
451}
452
453func createEthernetPerformanceMonitoringHistoryDataResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
Girish Gowdraa539f522021-02-15 23:00:45 -0800454 managedEntity, meErr := me.NewEthernetPerformanceMonitoringHistoryData(me.ParamData{
455 EntityID: entityID,
456 Attributes: me.AttributeValueMap{
457 "ManagedEntityId": entityID,
458 "IntervalEndTime": 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
459 "ThresholdData12Id": 0,
460 "FcsErrors": rand.Intn(100),
461 "ExcessiveCollisionCounter": rand.Intn(100),
462 "LateCollisionCounter": rand.Intn(100),
463 "FramesTooLong": rand.Intn(100),
464 "BufferOverflowsOnReceive": rand.Intn(100),
465 "BufferOverflowsOnTransmit": rand.Intn(100),
466 "SingleCollisionFrameCounter": rand.Intn(100),
467 "MultipleCollisionsFrameCounter": rand.Intn(100),
468 "SqeCounter": rand.Intn(100),
469 "DeferredTransmissionCounter": rand.Intn(100),
470 "InternalMacTransmitErrorCounter": rand.Intn(100),
471 "CarrierSenseErrorCounter": rand.Intn(100),
472 "AlignmentErrorCounter": rand.Intn(100),
473 "InternalMacReceiveErrorCounter": rand.Intn(100),
474 },
475 })
476
477 if meErr.GetError() != nil {
478 omciLogger.Errorf("NewEthernetPerformanceMonitoringHistoryData %v", meErr.Error())
479 return nil
480 }
481
482 // L2 PM counters MEs exceed max allowed OMCI payload size.
483 // So the request/responses are always multipart.
484 // First identify the attributes that are not requested in the current GET request.
485 // Then filter out those attributes from the responses in the current GET response.
486 unwantedAttributeMask := ^attributeMask
487 var i uint16
488 for i = 1; i <= 16; i++ { // 1 and 16 because they are allowed valid min and max index keys in AttributeValueMap.
489 // We leave out 0 because that is ManagedEntity and that is a default IE in the map
490 if (1<<(16-i))&unwantedAttributeMask > 0 {
491 if err := managedEntity.DeleteAttributeByIndex(uint(i)); err != nil {
492 omciLogger.Errorf("error deleting attribute at index=%v, err=%v", i, err)
493 }
494 }
495 }
496
497 return &omci.GetResponse{
498 MeBasePacket: omci.MeBasePacket{
499 EntityClass: me.EthernetPerformanceMonitoringHistoryDataClassID,
500 EntityInstance: entityID,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800501 },
502 Attributes: managedEntity.GetAttributeValueMap(),
503 AttributeMask: attributeMask,
504 Result: me.Success,
505 }
506}
507
Girish Gowdra6d9a1a42021-03-05 16:07:15 -0800508func createFecPerformanceMonitoringHistoryDataResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
509 managedEntity, meErr := me.NewFecPerformanceMonitoringHistoryData(me.ParamData{
510 EntityID: entityID,
511 Attributes: me.AttributeValueMap{
512 "ManagedEntityId": entityID,
513 "IntervalEndTime": 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
514 "ThresholdData12Id": 0,
515 "CorrectedBytes": rand.Intn(100),
516 "CorrectedCodeWords": rand.Intn(100),
517 "UncorrectableCodeWords": rand.Intn(100),
518 "TotalCodeWords": rand.Intn(100),
519 "FecSeconds": rand.Intn(100),
520 },
521 })
522
523 if meErr.GetError() != nil {
524 omciLogger.Errorf("NewFecPerformanceMonitoringHistoryData %v", meErr.Error())
525 return nil
526 }
527
528 // FEC History counter fits within single gem payload.
529 // No need of the logical we use in other Ethernet History counters or Gem Port History counters
530
531 return &omci.GetResponse{
532 MeBasePacket: omci.MeBasePacket{
533 EntityClass: me.FecPerformanceMonitoringHistoryDataClassID,
534 EntityInstance: entityID,
535 },
536 Attributes: managedEntity.GetAttributeValueMap(),
537 AttributeMask: attributeMask,
538 Result: me.Success,
539 }
540}
541
542func createGemPortNetworkCtpPerformanceMonitoringHistoryData(attributeMask uint16, entityID uint16) *omci.GetResponse {
543 managedEntity, meErr := me.NewGemPortNetworkCtpPerformanceMonitoringHistoryData(me.ParamData{
544 EntityID: entityID,
545 Attributes: me.AttributeValueMap{
546 "ManagedEntityId": entityID,
547 "IntervalEndTime": 0, // This ideally should increment by 1 every collection interval, but staying 0 for simulation is Ok for now.
548 "ThresholdData12Id": 0,
549 "TransmittedGemFrames": rand.Intn(100),
550 "ReceivedGemFrames": rand.Intn(100),
551 "ReceivedPayloadBytes": rand.Intn(100),
552 "TransmittedPayloadBytes": rand.Intn(100),
553 "EncryptionKeyErrors": rand.Intn(100),
554 },
555 })
556
557 if meErr.GetError() != nil {
558 omciLogger.Errorf("NewGemPortNetworkCtpPerformanceMonitoringHistoryData %v", meErr.Error())
559 return nil
560 }
561
562 // L2 PM counters MEs exceed max allowed OMCI payload size.
563 // So the request/responses are always multipart.
564 // First identify the attributes that are not requested in the current GET request.
565 // Then filter out those attributes from the responses in the current GET response.
566 unwantedAttributeMask := ^attributeMask
567 var i uint16
568 for i = 1; i <= 7; i++ { // 1 and 7 because they are allowed valid min and max index keys in AttributeValueMap.
569 // We leave out 0 because that is ManagedEntity and that is a default IE in the map
570 if (1<<(7-i))&unwantedAttributeMask > 0 {
571 if err := managedEntity.DeleteAttributeByIndex(uint(i)); err != nil {
572 omciLogger.Errorf("error deleting attribute at index=%v, err=%v", i, err)
573 }
574 }
575 }
576
577 return &omci.GetResponse{
578 MeBasePacket: omci.MeBasePacket{
579 EntityClass: me.GemPortNetworkCtpPerformanceMonitoringHistoryDataClassID,
580 EntityInstance: entityID,
581 },
582 Attributes: managedEntity.GetAttributeValueMap(),
583 AttributeMask: attributeMask,
584 Result: me.Success,
585 }
586}
587
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800588func createOnuDataResponse(attributeMask uint16, entityID uint16, mds uint8) *omci.GetResponse {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800589 managedEntity, meErr := me.NewOnuData(me.ParamData{
590 EntityID: entityID,
591 Attributes: me.AttributeValueMap{
592 "ManagedEntityId": entityID,
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800593 "MibDataSync": mds,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800594 },
595 })
596
597 if meErr.GetError() != nil {
598 omciLogger.Errorf("NewOnuData %v", meErr.Error())
599 return nil
600 }
601
602 return &omci.GetResponse{
603 MeBasePacket: omci.MeBasePacket{
Girish Gowdraa539f522021-02-15 23:00:45 -0800604 EntityClass: me.OnuDataClassID,
605 EntityInstance: entityID,
606 },
607 Attributes: managedEntity.GetAttributeValueMap(),
608 AttributeMask: attributeMask,
609 Result: me.Success,
610 }
611}
612
613func createAnigResponse(attributeMask uint16, entityID uint16) *omci.GetResponse {
614 managedEntity, meErr := me.NewAniG(me.ParamData{
615 EntityID: entityID,
616 Attributes: me.AttributeValueMap{
617 "ManagedEntityId": entityID,
618 "SrIndication": 0,
619 "TotalTcontNumber": 0,
620 "GemBlockLength": 0,
621 "PiggybackDbaReporting": 0,
622 "Deprecated": 0,
623 "SignalFailThreshold": 0,
624 "SignalDegradeThreshold": 0,
625 "Arc": 0,
626 "ArcInterval": 0,
627 "OpticalSignalLevel": rand.Intn(16000), // generate some random power level than defaulting to 0
628 "LowerOpticalThreshold": 0,
629 "UpperOpticalThreshold": 0,
630 "OnuResponseTime": 0,
631 "TransmitOpticalLevel": rand.Intn(16000), // generate some random power level than defaulting to 0
632 "LowerTransmitPowerThreshold": 0,
633 "UpperTransmitPowerThreshold": 0,
634 },
635 })
636
637 if meErr.GetError() != nil {
638 omciLogger.Errorf("NewAniG %v", meErr.Error())
639 return nil
640 }
641
642 return &omci.GetResponse{
643 MeBasePacket: omci.MeBasePacket{
644 EntityClass: me.AniGClassID,
645 EntityInstance: entityID,
Matteo Scandolof9d43412021-01-12 11:11:34 -0800646 },
647 Attributes: managedEntity.GetAttributeValueMap(),
648 AttributeMask: attributeMask,
649 Result: me.Success,
650 }
651}
652
653func toOctets(str string, size int) []byte {
654 asciiBytes := []byte(str)
655
656 if len(asciiBytes) < size {
657 missing := size - len(asciiBytes)
658 for i := 0; i < missing; i++ {
659 asciiBytes = append(asciiBytes, []byte{0x00}[0])
660 }
661 }
662 return asciiBytes
663}