blob: fe02e5dc1f4a671744632e1e82126ae3a2edead8 [file] [log] [blame]
Matteo Scandolo40e067f2019-10-16 16:59:41 -07001/*
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"
Matteo Scandolof9d43412021-01-12 11:11:34 -080021 "errors"
Matteo Scandolo40e067f2019-10-16 16:59:41 -070022 "github.com/google/gopacket"
Matteo Scandolof9d43412021-01-12 11:11:34 -080023 "github.com/opencord/omci-lib-go"
24 me "github.com/opencord/omci-lib-go/generated"
Matteo Scandolo40e067f2019-10-16 16:59:41 -070025 log "github.com/sirupsen/logrus"
26)
27
28var omciLogger = log.WithFields(log.Fields{
29 "module": "OMCI",
30})
31
32const galEthernetEID = uint16(1)
33const maxGemPayloadSize = uint16(48)
34const gemEID = uint16(1)
35
36type txFrameCreator func() ([]byte, error)
37type rxFrameParser func(gopacket.Packet) error
38
39type ServiceStep struct {
40 MakeTxFrame txFrameCreator
41 RxHandler rxFrameParser
42}
43
Matteo Scandolof9d43412021-01-12 11:11:34 -080044// NOTE this is basically the same as https://github.com/opencord/voltha-openonu-adapter-go/blob/master/internal/pkg/onuadaptercore/omci_cc.go#L545-L564
45// we should probably move it in "omci-lib-go"
Matteo Scandolo40e067f2019-10-16 16:59:41 -070046func serialize(msgType omci.MessageType, request gopacket.SerializableLayer, tid uint16) ([]byte, error) {
47 omciLayer := &omci.OMCI{
48 TransactionID: tid,
49 MessageType: msgType,
50 }
51 var options gopacket.SerializeOptions
52 options.FixLengths = true
53
54 buffer := gopacket.NewSerializeBuffer()
55 err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
56 if err != nil {
57 return nil, err
58 }
59 return buffer.Bytes(), nil
60}
61
62func hexEncode(omciPkt []byte) ([]byte, error) {
63 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
64 hex.Encode(dst, omciPkt)
65 return dst, nil
66}
67
Matteo Scandolo40e067f2019-10-16 16:59:41 -070068func CreateMibResetRequest(tid uint16) ([]byte, error) {
69
70 request := &omci.MibResetRequest{
71 MeBasePacket: omci.MeBasePacket{
Matteo Scandolof9d43412021-01-12 11:11:34 -080072 EntityClass: me.OnuDataClassID,
Matteo Scandolo40e067f2019-10-16 16:59:41 -070073 },
74 }
75 pkt, err := serialize(omci.MibResetRequestType, request, tid)
76 if err != nil {
77 omciLogger.WithFields(log.Fields{
78 "Err": err,
79 }).Fatalf("Cannot serialize MibResetRequest")
80 return nil, err
81 }
82 return hexEncode(pkt)
83}
84
Matteo Scandolof9d43412021-01-12 11:11:34 -080085func CreateMibResetResponse(tid uint16) ([]byte, error) {
86
87 // TODO reset MDX
88 request := &omci.MibResetResponse{
89 MeBasePacket: omci.MeBasePacket{
90 EntityClass: me.OnuDataClassID,
91 },
92 Result: me.Success,
93 }
94 pkt, err := serialize(omci.MibResetResponseType, request, tid)
95 if err != nil {
96 omciLogger.WithFields(log.Fields{
97 "Err": err,
98 }).Error("Cannot serialize MibResetResponse")
99 return nil, err
100 }
101 return pkt, nil
102}
103
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700104func CreateMibUploadRequest(tid uint16) ([]byte, error) {
105 request := &omci.MibUploadRequest{
106 MeBasePacket: omci.MeBasePacket{
Matteo Scandolof9d43412021-01-12 11:11:34 -0800107 EntityClass: me.OnuDataClassID,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700108 // Default Instance ID is 0
109 },
110 }
111 pkt, err := serialize(omci.MibUploadRequestType, request, tid)
112 if err != nil {
113 omciLogger.WithFields(log.Fields{
114 "Err": err,
115 }).Fatalf("Cannot serialize MibUploadRequest")
116 return nil, err
117 }
118 return hexEncode(pkt)
119}
120
Matteo Scandolof9d43412021-01-12 11:11:34 -0800121func CreateMibUploadResponse(tid uint16) ([]byte, error) {
122
123 numberOfCommands := uint16(291) //NOTE should this be configurable? (not until we have moved all the messages away from omci-sim)
124
125 request := &omci.MibUploadResponse{
126 MeBasePacket: omci.MeBasePacket{
127 EntityClass: me.OnuDataClassID,
128 },
129 NumberOfCommands: numberOfCommands,
130 }
131 pkt, err := serialize(omci.MibUploadResponseType, request, tid)
132 if err != nil {
133 omciLogger.WithFields(log.Fields{
134 "Err": err,
135 }).Error("Cannot serialize MibUploadResponse")
136 return nil, err
137 }
138 return pkt, nil
139}
140
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700141func CreateMibUploadNextRequest(tid uint16, seqNumber uint16) ([]byte, error) {
142
143 request := &omci.MibUploadNextRequest{
144 MeBasePacket: omci.MeBasePacket{
Matteo Scandolof9d43412021-01-12 11:11:34 -0800145 EntityClass: me.OnuDataClassID,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700146 // Default Instance ID is 0
147 },
148 CommandSequenceNumber: seqNumber,
149 }
150 pkt, err := serialize(omci.MibUploadNextRequestType, request, tid)
151
152 if err != nil {
153 omciLogger.WithFields(log.Fields{
154 "Err": err,
155 }).Fatalf("Cannot serialize MibUploadNextRequest")
156 return nil, err
157 }
158 return hexEncode(pkt)
159}
160
Matteo Scandolof9d43412021-01-12 11:11:34 -0800161func ParseMibUploadNextRequest(omciPkt gopacket.Packet) (*omci.MibUploadNextRequest, error) {
162 msgLayer := omciPkt.Layer(omci.LayerTypeMibUploadNextRequest)
163 if msgLayer == nil {
164 err := "omci Msg layer could not be detected for LayerTypeMibUploadNextRequest"
165 omciLogger.Error(err)
166 return nil, errors.New(err)
Scott Bakerb90c4312020-03-12 21:33:25 -0700167 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800168 msgObj, msgOk := msgLayer.(*omci.MibUploadNextRequest)
169 if !msgOk {
170 err := "omci Msg layer could not be assigned for MibUploadNextRequest"
171 omciLogger.Error(err)
172 return nil, errors.New(err)
173 }
174 return msgObj, nil
Scott Bakerb90c4312020-03-12 21:33:25 -0700175}
176
Matteo Scandolof9d43412021-01-12 11:11:34 -0800177func CreateMibUploadNextResponse(omciPkt gopacket.Packet, omciMsg *omci.OMCI) ([]byte, error) {
Scott Bakerb90c4312020-03-12 21:33:25 -0700178
Matteo Scandolof9d43412021-01-12 11:11:34 -0800179 msgObj, err := ParseMibUploadNextRequest(omciPkt)
Scott Bakerb90c4312020-03-12 21:33:25 -0700180 if err != nil {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800181 err := "omci Msg layer could not be assigned for LayerTypeGetRequest"
182 omciLogger.Error(err)
183 return nil, errors.New(err)
Scott Bakerb90c4312020-03-12 21:33:25 -0700184 }
185
Matteo Scandolof9d43412021-01-12 11:11:34 -0800186 omciLogger.WithFields(log.Fields{
187 "EntityClass": msgObj.EntityClass,
188 "EntityInstance": msgObj.EntityInstance,
189 "CommandSequenceNumber": msgObj.CommandSequenceNumber,
190 }).Trace("received-omci-mibUploadNext-request")
Scott Bakerb90c4312020-03-12 21:33:25 -0700191
Matteo Scandolof9d43412021-01-12 11:11:34 -0800192 // depending on the sequenceNumber we'll report a different
193 reportedMe := &me.ManagedEntity{}
194 var meErr me.OmciErrors
195 //var entityInstance uint16
196 switch msgObj.CommandSequenceNumber {
197 case 0:
198 reportedMe, meErr = me.NewOnuData(me.ParamData{Attributes: me.AttributeValueMap{
199 "ManagedEntityId": me.OnuDataClassID,
200 "MibDataSync": 0,
201 }})
202 if meErr.GetError() != nil {
203 omciLogger.Errorf("NewOnuData %v", meErr.Error())
204 }
Scott Bakerb90c4312020-03-12 21:33:25 -0700205
Matteo Scandolof9d43412021-01-12 11:11:34 -0800206 case 1:
207 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
208 "ManagedEntityId": me.CircuitPackClassID,
209 "Type": 47,
210 "NumberOfPorts": 4,
211 "SerialNumber": toOctets("BBSM-Circuit-Pack", 20),
212 "Version": toOctets("v0.0.1", 20),
213 }})
214 if meErr.GetError() != nil {
215 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
216 }
217 case 2:
218 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
219 "ManagedEntityId": me.CircuitPackClassID,
220 "VendorId": "ONF",
221 "AdministrativeState": 0,
222 "OperationalState": 0,
223 "BridgedOrIpInd": 0,
224 }})
225 if meErr.GetError() != nil {
226 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
227 }
228 case 3:
229 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
230 "ManagedEntityId": me.CircuitPackClassID,
231 "EquipmentId": toOctets("BBSM-Circuit-Pack", 20),
232 "CardConfiguration": 0,
233 "TotalTContBufferNumber": 0,
234 "TotalPriorityQueueNumber": 8,
235 "TotalTrafficSchedulerNumber": 0,
236 }})
237 if meErr.GetError() != nil {
238 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
239 }
240 case 4:
241 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
242 "ManagedEntityId": me.CircuitPackClassID,
243 "PowerShedOverride": uint32(0),
244 }})
245 if meErr.GetError() != nil {
246 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
247 }
248 case 5:
249 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
250 "ManagedEntityId": me.CircuitPackClassID,
251 "Type": 238,
252 "NumberOfPorts": 1,
253 "SerialNumber": toOctets("BBSM-Circuit-Pack-2", 20),
254 "Version": toOctets("v0.0.1", 20),
255 }})
256 if meErr.GetError() != nil {
257 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
258 }
259 case 6:
260 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
261 "ManagedEntityId": me.CircuitPackClassID,
262 "VendorId": "ONF",
263 "AdministrativeState": 0,
264 "OperationalState": 0,
265 "BridgedOrIpInd": 0,
266 }})
267 if meErr.GetError() != nil {
268 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
269 }
270 case 7:
271 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
272 "ManagedEntityId": me.CircuitPackClassID,
273 "EquipmentId": toOctets("BBSM-Circuit-Pack", 20),
274 "CardConfiguration": 0,
275 "TotalTContBufferNumber": 8,
276 "TotalPriorityQueueNumber": 40,
277 "TotalTrafficSchedulerNumber": 10,
278 }})
279 if meErr.GetError() != nil {
280 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
281 }
282 case 8:
283 reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
284 "ManagedEntityId": me.CircuitPackClassID,
285 "PowerShedOverride": uint32(0),
286 }})
287 if meErr.GetError() != nil {
288 omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
289 }
290 case 9, 10, 11, 12:
291 // NOTE we're reporting for different UNIs, the IDs are 257, 258, 259, 260
292 meInstance := 248 + msgObj.CommandSequenceNumber
293 reportedMe, meErr = me.NewPhysicalPathTerminationPointEthernetUni(me.ParamData{
294 EntityID: meInstance,
295 Attributes: me.AttributeValueMap{
296 "ExpectedType": 0,
297 "SensedType": 47,
298 "AutoDetectionConfiguration": 0,
299 "EthernetLoopbackConfiguration": 0,
300 "AdministrativeState": 0,
301 "OperationalState": 0,
302 "ConfigurationInd": 3,
303 "MaxFrameSize": 1518,
304 "DteOrDceInd": 0,
305 "PauseTime": 0,
306 "BridgedOrIpInd": 2,
307 "Arc": 0,
308 "ArcInterval": 0,
309 "PppoeFilter": 0,
310 "PowerControl": 0,
311 }})
312 if meErr.GetError() != nil {
313 omciLogger.Errorf("NewPhysicalPathTerminationPointEthernetUni %v", meErr.Error())
314 }
315 case 13, 14, 15, 16, 17, 18, 19, 20:
316 // TODO report different MeID (see omci-sim pcap filter "frame[22:2] == 01:06")
317 reportedMe, meErr = me.NewTCont(me.ParamData{Attributes: me.AttributeValueMap{
318 "ManagedEntityId": me.TContClassID,
319 "AllocId": 0,
320 }})
321 if meErr.GetError() != nil {
322 omciLogger.Errorf("NewTCont %v", meErr.Error())
323 }
324 case 21:
325 reportedMe, meErr = me.NewAniG(me.ParamData{Attributes: me.AttributeValueMap{
326 "ManagedEntityId": me.AniGClassID,
327 "SrIndication": 1,
328 "TotalTcontNumber": 8,
329 "GemBlockLength": 30,
330 "PiggybackDbaReporting": 0,
331 "Deprecated": 0,
332 "SignalFailThreshold": 5,
333 "SignalDegradeThreshold": 9,
334 "Arc": 0,
335 "ArcInterval": 0,
336 "OpticalSignalLevel": 57428,
337 "LowerOpticalThreshold": 255,
338 "UpperOpticalThreshold": 255,
339 "OnuResponseTime": 0,
340 "TransmitOpticalLevel": 3171,
341 "LowerTransmitPowerThreshold": 129,
342 "UpperTransmitPowerThreshold": 129,
343 }})
344 if meErr.GetError() != nil {
345 omciLogger.Errorf("NewAniG %v", meErr.Error())
346 }
347 case 22, 23, 24, 25:
348 // TODO report different MeID (see omci-sim pcap filter "frame[22:2] == 01:08")
349 reportedMe, meErr = me.NewUniG(me.ParamData{Attributes: me.AttributeValueMap{
350 "ManagedEntityId": me.UniGClassID,
351 "Deprecated": 0,
352 "AdministrativeState": 0,
353 }})
354 if meErr.GetError() != nil {
355 omciLogger.Errorf("NewUniG %v", meErr.Error())
356 }
357 case 26, 30, 34, 38, 42, 46, 50, 54,
358 58, 62, 66, 70, 74, 78, 82, 86,
359 90, 94, 98, 102, 106, 110, 114, 118,
360 122, 126, 130, 134, 138, 142, 146, 150,
361 154, 158, 162, 166, 170, 174, 178, 182,
362 186, 190, 194, 198, 202, 206, 210, 214,
363 218, 222, 226, 230, 234, 238, 242, 246,
364 250, 254, 258, 262, 266, 270, 274, 278:
365 case 27, 31, 35, 39, 43, 47, 51, 55,
366 59, 63, 67, 71, 75, 79, 83, 87,
367 91, 95, 99, 103, 107, 111, 115, 119,
368 123, 127, 131, 135, 139, 143, 147, 151,
369 155, 159, 163, 167, 171, 175, 179, 183,
370 187, 191, 195, 199, 203, 207, 211, 215,
371 219, 223, 227, 231, 235, 239, 243, 247,
372 251, 255, 259, 263, 267, 271, 275, 279:
373 case 28, 32, 36, 40, 44, 48, 52, 56,
374 60, 64, 68, 72, 76, 80, 84, 88,
375 92, 96, 100, 104, 108, 112, 116, 120,
376 124, 128, 132, 136, 140, 144, 148, 152,
377 156, 160, 164, 168, 172, 176, 180, 184,
378 188, 192, 196, 200, 204, 208, 212, 216,
379 220, 224, 228, 232, 236, 240, 244, 248,
380 252, 256, 260, 264, 268, 272, 276, 280:
381 case 29, 33, 37, 41, 45, 49, 53, 57,
382 61, 65, 69, 73, 77, 81, 85, 89,
383 93, 97, 101, 105, 109, 113, 117, 121,
384 125, 129, 133, 137, 141, 145, 149, 153,
385 157, 161, 165, 169, 173, 177, 181, 185,
386 189, 193, 197, 201, 205, 209, 213, 217,
387 221, 225, 229, 233, 237, 241, 245, 249,
388 253, 257, 261, 265, 269, 273, 277, 281:
389 reportedMe, meErr = me.NewPriorityQueue(me.ParamData{Attributes: me.AttributeValueMap{
390 "ManagedEntityId": me.PriorityQueueClassID,
391 "QueueConfigurationOption": 0,
392 "MaximumQueueSize": 100,
393 "AllocatedQueueSize": 100,
394 "DiscardBlockCounterResetInterval": 0,
395 "ThresholdValueForDiscardedBlocksDueToBufferOverflow": 0,
396 "RelatedPort": 80010000, // does this need to change?
397 "TrafficSchedulerPointer": 8008, // does this need to change?
398 "Weight": 1,
399 "BackPressureOperation": 1,
400 "BackPressureTime": 0,
401 "BackPressureOccurQueueThreshold": 0,
402 "BackPressureClearQueueThreshold": 0,
403 }})
404 if meErr.GetError() != nil {
405 omciLogger.Errorf("NewPriorityQueue %v", meErr.Error())
406 }
407 case 282, 283, 284, 285, 286, 287, 288, 289:
408 reportedMe, meErr = me.NewTrafficScheduler(me.ParamData{Attributes: me.AttributeValueMap{
409 "ManagedEntityId": me.TrafficSchedulerClassID,
410 "TContPointer": 8008, // NOTE does this need to change?
411 "TrafficSchedulerPointer": 0,
412 "Policy": 02,
413 "PriorityWeight": 0,
414 }})
415 if meErr.GetError() != nil {
416 omciLogger.Errorf("NewTrafficScheduler %v", meErr.Error())
417 }
418 case 290:
419 reportedMe, meErr = me.NewOnu2G(me.ParamData{Attributes: me.AttributeValueMap{
420 "ManagedEntityId": me.Onu2GClassID,
421 "TotalPriorityQueueNumber": 40,
422 "SecurityMode": 1,
423 "TotalTrafficSchedulerNumber": 8,
424 "TotalGemPortIdNumber": 0,
425 "Sysuptime": 0,
426 }})
427 if meErr.GetError() != nil {
428 omciLogger.Errorf("NewOnu2G %v", meErr.Error())
429 }
430 default:
431 omciLogger.Warn("unsupported-CommandSequenceNumber-in-mib-upload-next", msgObj.CommandSequenceNumber)
432 return nil, nil
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700433 }
434
Matteo Scandolof9d43412021-01-12 11:11:34 -0800435 response := &omci.MibUploadNextResponse{
436 MeBasePacket: omci.MeBasePacket{
437 EntityClass: me.OnuDataClassID,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700438 },
Matteo Scandolof9d43412021-01-12 11:11:34 -0800439 ReportedME: *reportedMe,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700440 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700441
Matteo Scandolof9d43412021-01-12 11:11:34 -0800442 omciLogger.WithFields(log.Fields{
443 "reportedMe": reportedMe,
444 }).Trace("created-omci-mibUploadNext-response")
445
446 pkt, err := serialize(omci.MibUploadNextResponseType, response, omciMsg.TransactionID)
447
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700448 if err != nil {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800449 omciLogger.WithFields(log.Fields{
450 "Err": err,
451 }).Fatalf("Cannot serialize MibUploadNextRequest")
452 return nil, err
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700453 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700454
Matteo Scandolof9d43412021-01-12 11:11:34 -0800455 return pkt, nil
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700456}