blob: 79ba3a51b783363bfb94866e81bd1d04b897044b [file] [log] [blame]
Matteo Scandoloef4e8f82021-05-17 11:20:49 -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 (
Matteo Scandolo8a574812021-05-20 15:18:53 -070020 "bytes"
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070021 "encoding/binary"
22 "encoding/hex"
Elia Battistonac63b112022-01-12 18:40:49 +010023
Andrea Campanella10426e22021-10-15 17:58:04 +020024 me "github.com/opencord/omci-lib-go/v2/generated"
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070025)
26
27type MibDbEntry struct {
28 classId me.ClassID
29 entityId EntityID
30 params me.AttributeValueMap
31}
32
33type MibDb struct {
34 NumberOfCommands uint16
35 items []MibDbEntry
36}
37
38type EntityID []byte
39
40func (e EntityID) ToString() string {
41 return hex.EncodeToString(e)
42}
43
44func (e EntityID) ToUint16() uint16 {
45 return binary.BigEndian.Uint16(e)
46}
47
48func (e EntityID) ToUint32() uint32 {
49 return binary.BigEndian.Uint32(e)
50}
51
Matteo Scandolo8a574812021-05-20 15:18:53 -070052func (e EntityID) FromUint16(id uint16) EntityID {
53 buff := new(bytes.Buffer)
54 err := binary.Write(buff, binary.BigEndian, id)
55 if err != nil {
56 panic(err)
57 }
58
59 return buff.Bytes()
60}
61
62func (e EntityID) Equals(i EntityID) bool {
63 if res := bytes.Compare(e, i); res == 0 {
64 return true
65 }
66 return false
67}
68
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070069const (
70 cardHolderOnuType byte = 0x01 // ONU is a single piece of integrated equipment
71 ethernetUnitType byte = 0x2f // Ethernet BASE-T
72 xgsPonUnitType byte = 0xee // XG-PON10G10
Elia Battistonac63b112022-01-12 18:40:49 +010073 potsUnitType byte = 0x20 // POTS
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070074 cardHolderSlotID byte = 0x01
75 tcontSlotId byte = 0x80 // why is this not the same as the cardHolderSlotID, it does not point to anything
76 aniGId byte = 0x01
77
78 upstreamPriorityQueues = 8 // Number of queues for each T-CONT
79 downstreamPriorityQueues = 16 // Number of queues for each PPTP
80 tconts = 8 // NOTE will we ever need to configure this?
81 // trafficSchedulers = 8 // NOTE will we ever need to configure this?
82)
83
84var (
85 cardHolderEntityID = EntityID{cardHolderOnuType, cardHolderSlotID}
86 circuitPackEntityID = cardHolderEntityID // is the same as that of the cardholder ME containing this circuit pack instance
87)
88
89func GenerateUniPortEntityId(id uint32) EntityID {
90 return EntityID{cardHolderSlotID, byte(id)}
91}
92
93// creates a MIB database for a ONU
94// CircuitPack and CardHolder are static, everything else can be configured
Elia Battistonac63b112022-01-12 18:40:49 +010095func GenerateMibDatabase(ethUniPortCount int, potsUniPortCount int) (*MibDb, error) {
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070096
97 mibDb := MibDb{
98 items: []MibDbEntry{},
99 }
100
101 // the first element to return is the ONU-Data
102 mibDb.items = append(mibDb.items, MibDbEntry{
103 me.OnuDataClassID,
104 EntityID{0x00, 0x00},
105 me.AttributeValueMap{"MibDataSync": 0}, // FIXME this needs to be parametrized before sending the response
106 })
107
108 // then we report the CardHolder
109 // NOTE we have not report it till now, so leave it commented out
110 //mibDb.items = append(mibDb.items, MibDbEntry{
111 // me.CardholderClassID,
112 // cardHolderEntityID,
113 // me.AttributeValueMap{
114 // "ActualPlugInUnitType": cardHolderOnuType,
115 // "ExpectedPlugInUnitType": ethernetUnitType,
116 // },
117 //})
118
119 // circuitPack XG-PON10G10
120 mibDb.items = append(mibDb.items, MibDbEntry{
121 me.CircuitPackClassID,
122 circuitPackEntityID,
123 me.AttributeValueMap{
124 "Type": xgsPonUnitType,
125 "NumberOfPorts": 1, // NOTE is this the ANI port? must be
126 "SerialNumber": ToOctets("BBSM-Circuit-Pack-ani", 20),
127 "Version": ToOctets("v0.0.1", 20),
128 },
129 })
130 mibDb.items = append(mibDb.items, MibDbEntry{
131 me.CircuitPackClassID,
132 circuitPackEntityID,
133 me.AttributeValueMap{
Elia Battistonac63b112022-01-12 18:40:49 +0100134 "VendorId": ToOctets("ONF", 4),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700135 "AdministrativeState": 0,
136 "OperationalState": 0,
137 "BridgedOrIpInd": 0,
138 },
139 })
140 mibDb.items = append(mibDb.items, MibDbEntry{
141 me.CircuitPackClassID,
142 circuitPackEntityID,
143 me.AttributeValueMap{
144 "EquipmentId": ToOctets("BBSM-Circuit-Pack", 20),
145 "CardConfiguration": 0,
146 "TotalTContBufferNumber": 8,
147 "TotalPriorityQueueNumber": 8,
148 "TotalTrafficSchedulerNumber": 0,
149 },
150 })
151 mibDb.items = append(mibDb.items, MibDbEntry{
152 me.CircuitPackClassID,
153 circuitPackEntityID,
154 me.AttributeValueMap{
155 "PowerShedOverride": uint32(0),
156 },
157 })
158
159 // ANI-G
160 mibDb.items = append(mibDb.items, MibDbEntry{
161 me.AniGClassID,
162 EntityID{tcontSlotId, aniGId},
163 me.AttributeValueMap{
164 "Arc": 0,
165 "ArcInterval": 0,
166 "Deprecated": 0,
167 "GemBlockLength": 48,
168 "LowerOpticalThreshold": 255,
169 "LowerTransmitPowerThreshold": 129,
170 "OnuResponseTime": 0,
171 "OpticalSignalLevel": 57428,
172 "PiggybackDbaReporting": 0,
173 "SignalDegradeThreshold": 9,
174 "SignalFailThreshold": 5,
175 "SrIndication": 1,
176 "TotalTcontNumber": 8,
177 "TransmitOpticalLevel": 3171,
178 "UpperOpticalThreshold": 255,
179 "UpperTransmitPowerThreshold": 129,
180 },
181 })
182
183 // circuitPack Ethernet
184 // NOTE the circuit pack is divided in multiple messages as too big to fit in a single one
185 mibDb.items = append(mibDb.items, MibDbEntry{
186 me.CircuitPackClassID,
187 circuitPackEntityID,
188 me.AttributeValueMap{
189 "Type": ethernetUnitType,
Elia Battistonac63b112022-01-12 18:40:49 +0100190 "NumberOfPorts": ethUniPortCount,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700191 "SerialNumber": ToOctets("BBSM-Circuit-Pack", 20),
192 "Version": ToOctets("v0.0.1", 20),
193 },
194 })
195 mibDb.items = append(mibDb.items, MibDbEntry{
196 me.CircuitPackClassID,
197 circuitPackEntityID,
198 me.AttributeValueMap{
Elia Battistonac63b112022-01-12 18:40:49 +0100199 "VendorId": ToOctets("ONF", 4),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700200 "AdministrativeState": 0,
201 "OperationalState": 0,
202 "BridgedOrIpInd": 0,
203 },
204 })
205 mibDb.items = append(mibDb.items, MibDbEntry{
206 me.CircuitPackClassID,
207 circuitPackEntityID,
208 me.AttributeValueMap{
209 "EquipmentId": ToOctets("BBSM-Circuit-Pack", 20),
210 "CardConfiguration": 0,
211 "TotalTContBufferNumber": 8,
212 "TotalPriorityQueueNumber": 8,
213 "TotalTrafficSchedulerNumber": 16,
214 },
215 })
216 mibDb.items = append(mibDb.items, MibDbEntry{
217 me.CircuitPackClassID,
218 circuitPackEntityID,
219 me.AttributeValueMap{
220 "PowerShedOverride": uint32(0),
221 },
222 })
223
Elia Battistonac63b112022-01-12 18:40:49 +0100224 if potsUniPortCount > 0 {
225 // circuitPack POTS
226 // NOTE the circuit pack is divided in multiple messages as too big to fit in a single one
227 mibDb.items = append(mibDb.items, MibDbEntry{
228 me.CircuitPackClassID,
229 circuitPackEntityID,
230 me.AttributeValueMap{
231 "Type": potsUnitType,
232 "NumberOfPorts": potsUniPortCount,
233 "SerialNumber": ToOctets("BBSM-Circuit-Pack", 20),
234 "Version": ToOctets("v0.0.1", 20),
235 },
236 })
237 mibDb.items = append(mibDb.items, MibDbEntry{
238 me.CircuitPackClassID,
239 circuitPackEntityID,
240 me.AttributeValueMap{
241 "VendorId": ToOctets("ONF", 4),
242 "AdministrativeState": 0,
243 "OperationalState": 0,
244 "BridgedOrIpInd": 0,
245 },
246 })
247 mibDb.items = append(mibDb.items, MibDbEntry{
248 me.CircuitPackClassID,
249 circuitPackEntityID,
250 me.AttributeValueMap{
251 "EquipmentId": ToOctets("BBSM-Circuit-Pack", 20),
252 "CardConfiguration": 0,
253 "TotalTContBufferNumber": 8,
254 "TotalPriorityQueueNumber": 8,
255 "TotalTrafficSchedulerNumber": 16,
256 },
257 })
258 mibDb.items = append(mibDb.items, MibDbEntry{
259 me.CircuitPackClassID,
260 circuitPackEntityID,
261 me.AttributeValueMap{
262 "PowerShedOverride": uint32(0),
263 },
264 })
265 }
266
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700267 // PPTP and UNI-Gs
268 // NOTE this are dependent on the number of UNI this ONU supports
269 // Through an identical ID, the UNI-G ME is implicitly linked to an instance of a PPTP
Elia Battistonac63b112022-01-12 18:40:49 +0100270 totalPortsCount := ethUniPortCount + potsUniPortCount
271 for i := 1; i <= totalPortsCount; i++ {
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700272 uniEntityId := GenerateUniPortEntityId(uint32(i))
273
Elia Battistonac63b112022-01-12 18:40:49 +0100274 if i <= ethUniPortCount {
275 // first, create the correct amount of ethernet UNIs, the same is done in onu.go
276 mibDb.items = append(mibDb.items, MibDbEntry{
277 me.PhysicalPathTerminationPointEthernetUniClassID,
278 uniEntityId,
279 me.AttributeValueMap{
280 "ExpectedType": 0,
281 "SensedType": ethernetUnitType,
282 "AutoDetectionConfiguration": 0,
283 "EthernetLoopbackConfiguration": 0,
284 "AdministrativeState": 0,
285 "OperationalState": 0,
286 "ConfigurationInd": 3,
287 "MaxFrameSize": 1518,
288 "DteOrDceInd": 0,
289 "PauseTime": 0,
290 "BridgedOrIpInd": 2,
291 "Arc": 0,
292 "ArcInterval": 0,
293 "PppoeFilter": 0,
294 "PowerControl": 0,
295 },
296 })
297 } else {
298 // the remaining ones are pots UNIs, the same is done in onu.go
299 mibDb.items = append(mibDb.items, MibDbEntry{
300 me.PhysicalPathTerminationPointPotsUniClassID,
301 uniEntityId,
302 me.AttributeValueMap{
303 "AdministrativeState": 0,
304 "Deprecated": 0,
305 "Arc": 0,
306 "ArcInterval": 0,
307 "Impedance": 0,
308 "TransmissionPath": 0,
309 "RxGain": 0,
310 "TxGain": 0,
311 "OperationalState": 0,
312 "HookState": 0,
313 "PotsHoldoverTime": 0,
314 "NominalFeedVoltage": 0,
315 "LossOfSoftswitch": 0,
316 },
317 })
318 }
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700319
320 mibDb.items = append(mibDb.items, MibDbEntry{
321 me.UniGClassID,
322 uniEntityId,
323 me.AttributeValueMap{
324 "AdministrativeState": 0,
325 "Deprecated": 0,
326 "ManagementCapability": 0,
327 "NonOmciManagementIdentifier": 0,
328 "RelayAgentOptions": 0,
329 },
330 })
331
332 // Downstream Queues (related to PPTP)
333 // 16 priorities queues for each UNI Ports
334 // EntityID = cardHolderSlotID + Uni EntityID (0101)
335 for j := 1; j <= downstreamPriorityQueues; j++ {
336 queueEntityId := EntityID{cardHolderSlotID, byte(j)}
337
338 // we first report the PriorityQueue without any attribute
339 mibDb.items = append(mibDb.items, MibDbEntry{
340 me.PriorityQueueClassID,
341 queueEntityId, //was not reported in the original implementation
342 me.AttributeValueMap{},
343 })
344
345 // then we report it with the required attributes
346 // In the downstream direction, the first byte is the slot number and the second byte is the port number of the queue's destination port.
347 relatedPort := append(uniEntityId, 0x00, byte(j))
348 mibDb.items = append(mibDb.items, MibDbEntry{
349 me.PriorityQueueClassID,
350 queueEntityId, //was not reported in the original implementation
351 me.AttributeValueMap{
352 "QueueConfigurationOption": 0,
353 "MaximumQueueSize": 100,
354 "AllocatedQueueSize": 100,
355 "DiscardBlockCounterResetInterval": 0,
356 "ThresholdValueForDiscardedBlocksDueToBufferOverflow": 0,
357 "RelatedPort": relatedPort.ToUint32(),
358 "TrafficSchedulerPointer": 0, //it was hardcoded to 0x0108 in the current implementation
359 "Weight": 1,
360 "BackPressureOperation": 1,
361 "BackPressureTime": 0,
362 "BackPressureOccurQueueThreshold": 0,
363 "BackPressureClearQueueThreshold": 0,
364 },
365 })
366 }
367 }
368
369 // T-CONTS and Traffic Schedulers
370 for i := 1; i <= tconts; i++ {
371 tcontEntityId := EntityID{tcontSlotId, byte(i)}
372
373 mibDb.items = append(mibDb.items, MibDbEntry{
374 me.TContClassID,
375 tcontEntityId,
376 me.AttributeValueMap{
377 "AllocId": 65535,
378 },
379 })
380
381 tsEntityId := EntityID{cardHolderSlotID, byte(i)}
382 mibDb.items = append(mibDb.items, MibDbEntry{
383 me.TrafficSchedulerClassID,
384 tsEntityId, //was not reported in the original implementation
385 me.AttributeValueMap{
386 "TContPointer": tcontEntityId.ToUint16(), // was hardcoded to a non-existing t-cont
387 "TrafficSchedulerPointer": 0,
388 "Policy": 02,
389 "PriorityWeight": 0,
390 },
391 })
392
393 for j := 1; j <= upstreamPriorityQueues; j++ {
394 queueEntityId := EntityID{tcontSlotId, byte(j)}
395 // Upstream Queues (related to traffic schedulers)
396 // 8 priorities queues per TCONT
397 // EntityID = tcontSlotId + Uni EntityID (8001)
398
399 // we first report the PriorityQueue without any attribute
400 mibDb.items = append(mibDb.items, MibDbEntry{
401 me.PriorityQueueClassID,
402 queueEntityId, //was not reported in the original implementation
403 me.AttributeValueMap{},
404 })
405
406 // then we report it with the required attributes
407 // In the upstream direction, the first 2 bytes are the ME ID of the associated T- CONT, the first byte of which is a slot number, the second byte a T-CONT number.
408 relatedPort := append(tcontEntityId, 0x00, byte(j))
409 mibDb.items = append(mibDb.items, MibDbEntry{
410 me.PriorityQueueClassID,
411 queueEntityId, //was not reported in the original implementation
412 me.AttributeValueMap{
413 "QueueConfigurationOption": 0,
414 "MaximumQueueSize": 100,
415 "AllocatedQueueSize": 100,
416 "DiscardBlockCounterResetInterval": 0,
417 "ThresholdValueForDiscardedBlocksDueToBufferOverflow": 0,
418 "RelatedPort": relatedPort.ToUint32(),
419 "TrafficSchedulerPointer": tsEntityId.ToUint16(), //it was hardcoded to 0x0108 in the current implementation
420 "Weight": 1,
421 "BackPressureOperation": 1,
422 "BackPressureTime": 0,
423 "BackPressureOccurQueueThreshold": 0,
424 "BackPressureClearQueueThreshold": 0,
425 },
426 })
427 }
428 }
429
430 // ONU-2g
431 mibDb.items = append(mibDb.items, MibDbEntry{
432 me.Onu2GClassID,
433 EntityID{0x00, 0x00},
434 me.AttributeValueMap{
435 "ConnectivityCapability": 127,
436 "CurrentConnectivityMode": 0,
437 "Deprecated": 1,
438 "PriorityQueueScaleFactor": 1,
439 "QualityOfServiceQosConfigurationFlexibility": 63,
440 "Sysuptime": 0,
441 "TotalGemPortIdNumber": 8,
442 "TotalPriorityQueueNumber": 64,
443 "TotalTrafficSchedulerNumber": 8,
444 },
445 })
446
447 mibDb.NumberOfCommands = uint16(len(mibDb.items))
448
449 return &mibDb, nil
450}