blob: 57ca21516d0608a1e75a3529542c75a24ec9d5e7 [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"
Holger Hildebrandt236e3742022-05-04 14:07:27 +000023 "fmt"
24 "strings"
25
Matteo Scandolocfedba42022-02-14 16:08:54 -080026 "github.com/google/gopacket"
Elia Battistonb7bea222022-02-18 16:25:00 +010027 "github.com/opencord/bbsim/internal/common"
Matteo Scandolocfedba42022-02-14 16:08:54 -080028 "github.com/opencord/omci-lib-go/v2"
Andrea Campanella10426e22021-10-15 17:58:04 +020029 me "github.com/opencord/omci-lib-go/v2/generated"
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070030)
31
Matteo Scandolocfedba42022-02-14 16:08:54 -080032// MibDbEntry contains all the information needed to build a
33// MibUploadNextResponse packet.
34// if Packet has a value all the other fields are ignored and the packet is sent as is.
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070035type MibDbEntry struct {
36 classId me.ClassID
37 entityId EntityID
38 params me.AttributeValueMap
Matteo Scandolocfedba42022-02-14 16:08:54 -080039 packet []byte
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070040}
41
42type MibDb struct {
Holger Hildebrandt236e3742022-05-04 14:07:27 +000043 NumberOfBaselineCommands uint16
44 NumberOfExtendedCommands uint16
45 baselineItems []MibDbEntry
46 extendedResponses [][]byte
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070047}
48
49type EntityID []byte
50
Holger Hildebrandt236e3742022-05-04 14:07:27 +000051const (
52 unknownMePktReportedMeHdr string = "002500018000"
53 unknownMePktAttributes string = "0102030405060708090A0B0C0D0E0F101112131415161718191A"
54 unknownAttribPktReportedMeHdr string = "0101000007FD"
55 unknownAttribPktAttributes string = "00400801000800000006007F07003F00010001000100"
56 extRespMsgContentsLenStart = 8
57 extRespMsgContentsLenEnd = 10
58)
59
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070060func (e EntityID) ToString() string {
61 return hex.EncodeToString(e)
62}
63
64func (e EntityID) ToUint16() uint16 {
65 return binary.BigEndian.Uint16(e)
66}
67
68func (e EntityID) ToUint32() uint32 {
69 return binary.BigEndian.Uint32(e)
70}
71
Matteo Scandolo8a574812021-05-20 15:18:53 -070072func (e EntityID) FromUint16(id uint16) EntityID {
73 buff := new(bytes.Buffer)
74 err := binary.Write(buff, binary.BigEndian, id)
75 if err != nil {
76 panic(err)
77 }
78
79 return buff.Bytes()
80}
81
82func (e EntityID) Equals(i EntityID) bool {
83 if res := bytes.Compare(e, i); res == 0 {
84 return true
85 }
86 return false
87}
88
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070089const (
90 cardHolderOnuType byte = 0x01 // ONU is a single piece of integrated equipment
91 ethernetUnitType byte = 0x2f // Ethernet BASE-T
92 xgsPonUnitType byte = 0xee // XG-PON10G10
Elia Battistonb7bea222022-02-18 16:25:00 +010093 gPonUnitType byte = 0xf5 // GPON12441244
Elia Battistonac63b112022-01-12 18:40:49 +010094 potsUnitType byte = 0x20 // POTS
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070095 cardHolderSlotID byte = 0x01
96 tcontSlotId byte = 0x80 // why is this not the same as the cardHolderSlotID, it does not point to anything
97 aniGId byte = 0x01
98
99 upstreamPriorityQueues = 8 // Number of queues for each T-CONT
100 downstreamPriorityQueues = 16 // Number of queues for each PPTP
101 tconts = 8 // NOTE will we ever need to configure this?
102 // trafficSchedulers = 8 // NOTE will we ever need to configure this?
103)
104
105var (
106 cardHolderEntityID = EntityID{cardHolderOnuType, cardHolderSlotID}
107 circuitPackEntityID = cardHolderEntityID // is the same as that of the cardholder ME containing this circuit pack instance
108)
109
110func GenerateUniPortEntityId(id uint32) EntityID {
111 return EntityID{cardHolderSlotID, byte(id)}
112}
113
114// creates a MIB database for a ONU
115// CircuitPack and CardHolder are static, everything else can be configured
Elia Battistonb7bea222022-02-18 16:25:00 +0100116func GenerateMibDatabase(ethUniPortCount int, potsUniPortCount int, technology common.PonTechnology) (*MibDb, error) {
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700117
118 mibDb := MibDb{
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000119 baselineItems: []MibDbEntry{},
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700120 }
121
122 // the first element to return is the ONU-Data
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000123 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700124 me.OnuDataClassID,
125 EntityID{0x00, 0x00},
Elia Battiston9bfe1102022-02-03 10:38:03 +0100126 me.AttributeValueMap{me.OnuData_MibDataSync: 0}, // FIXME this needs to be parametrized before sending the response
Matteo Scandolocfedba42022-02-14 16:08:54 -0800127 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700128 })
129
130 // then we report the CardHolder
131 // NOTE we have not report it till now, so leave it commented out
132 //mibDb.items = append(mibDb.items, MibDbEntry{
133 // me.CardholderClassID,
134 // cardHolderEntityID,
135 // me.AttributeValueMap{
136 // "ActualPlugInUnitType": cardHolderOnuType,
137 // "ExpectedPlugInUnitType": ethernetUnitType,
138 // },
139 //})
140
Elia Battistonb7bea222022-02-18 16:25:00 +0100141 // ANI circuitPack
142 var aniCPType byte
143
144 switch technology {
145 case common.XGSPON:
146 aniCPType = xgsPonUnitType
147 case common.GPON:
148 aniCPType = gPonUnitType
149 }
150
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000151 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700152 me.CircuitPackClassID,
153 circuitPackEntityID,
154 me.AttributeValueMap{
Elia Battistonb7bea222022-02-18 16:25:00 +0100155 me.CircuitPack_Type: aniCPType,
Elia Battiston9bfe1102022-02-03 10:38:03 +0100156 me.CircuitPack_NumberOfPorts: 1, // NOTE is this the ANI port? must be
157 me.CircuitPack_SerialNumber: ToOctets("BBSM-Circuit-Pack-ani", 20),
158 me.CircuitPack_Version: ToOctets("v0.0.1", 20),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700159 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800160 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700161 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000162 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700163 me.CircuitPackClassID,
164 circuitPackEntityID,
165 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100166 me.CircuitPack_VendorId: ToOctets("ONF", 4),
167 me.CircuitPack_AdministrativeState: 0,
168 me.CircuitPack_OperationalState: 0,
169 me.CircuitPack_BridgedOrIpInd: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700170 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800171 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700172 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000173 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700174 me.CircuitPackClassID,
175 circuitPackEntityID,
176 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100177 me.CircuitPack_EquipmentId: ToOctets("BBSM-Circuit-Pack", 20),
178 me.CircuitPack_CardConfiguration: 0,
179 me.CircuitPack_TotalTContBufferNumber: 8,
180 me.CircuitPack_TotalPriorityQueueNumber: 8,
181 me.CircuitPack_TotalTrafficSchedulerNumber: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700182 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800183 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700184 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000185 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700186 me.CircuitPackClassID,
187 circuitPackEntityID,
188 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100189 me.CircuitPack_PowerShedOverride: uint32(0),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700190 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800191 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700192 })
193
194 // ANI-G
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000195 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700196 me.AniGClassID,
197 EntityID{tcontSlotId, aniGId},
198 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100199 me.AniG_Arc: 0,
200 me.AniG_ArcInterval: 0,
201 me.AniG_Deprecated: 0,
202 me.AniG_GemBlockLength: 48,
203 me.AniG_LowerOpticalThreshold: 255,
204 me.AniG_LowerTransmitPowerThreshold: 129,
205 me.AniG_OnuResponseTime: 0,
206 me.AniG_OpticalSignalLevel: 57428,
207 me.AniG_PiggybackDbaReporting: 0,
208 me.AniG_SignalDegradeThreshold: 9,
209 me.AniG_SignalFailThreshold: 5,
210 me.AniG_SrIndication: 1,
211 me.AniG_TotalTcontNumber: 8,
212 me.AniG_TransmitOpticalLevel: 3171,
213 me.AniG_UpperOpticalThreshold: 255,
214 me.AniG_UpperTransmitPowerThreshold: 129,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700215 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800216 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700217 })
218
219 // circuitPack Ethernet
220 // NOTE the circuit pack is divided in multiple messages as too big to fit in a single one
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000221 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700222 me.CircuitPackClassID,
223 circuitPackEntityID,
224 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100225 me.CircuitPack_Type: ethernetUnitType,
226 me.CircuitPack_NumberOfPorts: ethUniPortCount,
227 me.CircuitPack_SerialNumber: ToOctets("BBSM-Circuit-Pack", 20),
228 me.CircuitPack_Version: ToOctets("v0.0.1", 20),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700229 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800230 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700231 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000232 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700233 me.CircuitPackClassID,
234 circuitPackEntityID,
235 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100236 me.CircuitPack_VendorId: ToOctets("ONF", 4),
237 me.CircuitPack_AdministrativeState: 0,
238 me.CircuitPack_OperationalState: 0,
239 me.CircuitPack_BridgedOrIpInd: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700240 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800241 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700242 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000243 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700244 me.CircuitPackClassID,
245 circuitPackEntityID,
246 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100247 me.CircuitPack_EquipmentId: ToOctets("BBSM-Circuit-Pack", 20),
248 me.CircuitPack_CardConfiguration: 0,
249 me.CircuitPack_TotalTContBufferNumber: 8,
250 me.CircuitPack_TotalPriorityQueueNumber: 8,
251 me.CircuitPack_TotalTrafficSchedulerNumber: 16,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700252 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800253 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700254 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000255 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700256 me.CircuitPackClassID,
257 circuitPackEntityID,
258 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100259 me.CircuitPack_PowerShedOverride: uint32(0),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700260 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800261 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700262 })
263
Elia Battistonac63b112022-01-12 18:40:49 +0100264 if potsUniPortCount > 0 {
265 // circuitPack POTS
266 // NOTE the circuit pack is divided in multiple messages as too big to fit in a single one
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000267 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Elia Battistonac63b112022-01-12 18:40:49 +0100268 me.CircuitPackClassID,
269 circuitPackEntityID,
270 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100271 me.CircuitPack_Type: potsUnitType,
272 me.CircuitPack_NumberOfPorts: potsUniPortCount,
273 me.CircuitPack_SerialNumber: ToOctets("BBSM-Circuit-Pack", 20),
274 me.CircuitPack_Version: ToOctets("v0.0.1", 20),
Elia Battistonac63b112022-01-12 18:40:49 +0100275 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800276 nil,
Elia Battistonac63b112022-01-12 18:40:49 +0100277 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000278 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Elia Battistonac63b112022-01-12 18:40:49 +0100279 me.CircuitPackClassID,
280 circuitPackEntityID,
281 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100282 me.CircuitPack_VendorId: ToOctets("ONF", 4),
283 me.CircuitPack_AdministrativeState: 0,
284 me.CircuitPack_OperationalState: 0,
285 me.CircuitPack_BridgedOrIpInd: 0,
Elia Battistonac63b112022-01-12 18:40:49 +0100286 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800287 nil,
Elia Battistonac63b112022-01-12 18:40:49 +0100288 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000289 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Elia Battistonac63b112022-01-12 18:40:49 +0100290 me.CircuitPackClassID,
291 circuitPackEntityID,
292 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100293 me.CircuitPack_EquipmentId: ToOctets("BBSM-Circuit-Pack", 20),
294 me.CircuitPack_CardConfiguration: 0,
295 me.CircuitPack_TotalTContBufferNumber: 8,
296 me.CircuitPack_TotalPriorityQueueNumber: 8,
297 me.CircuitPack_TotalTrafficSchedulerNumber: 16,
Elia Battistonac63b112022-01-12 18:40:49 +0100298 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800299 nil,
Elia Battistonac63b112022-01-12 18:40:49 +0100300 })
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000301 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Elia Battistonac63b112022-01-12 18:40:49 +0100302 me.CircuitPackClassID,
303 circuitPackEntityID,
304 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100305 me.CircuitPack_PowerShedOverride: uint32(0),
Elia Battistonac63b112022-01-12 18:40:49 +0100306 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800307 nil,
Elia Battistonac63b112022-01-12 18:40:49 +0100308 })
309 }
310
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700311 // PPTP and UNI-Gs
312 // NOTE this are dependent on the number of UNI this ONU supports
313 // Through an identical ID, the UNI-G ME is implicitly linked to an instance of a PPTP
Elia Battistonac63b112022-01-12 18:40:49 +0100314 totalPortsCount := ethUniPortCount + potsUniPortCount
315 for i := 1; i <= totalPortsCount; i++ {
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700316 uniEntityId := GenerateUniPortEntityId(uint32(i))
317
Elia Battistonac63b112022-01-12 18:40:49 +0100318 if i <= ethUniPortCount {
319 // first, create the correct amount of ethernet UNIs, the same is done in onu.go
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000320 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Elia Battistonac63b112022-01-12 18:40:49 +0100321 me.PhysicalPathTerminationPointEthernetUniClassID,
322 uniEntityId,
323 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100324 me.PhysicalPathTerminationPointEthernetUni_ExpectedType: 0,
325 me.PhysicalPathTerminationPointEthernetUni_SensedType: ethernetUnitType,
326 me.PhysicalPathTerminationPointEthernetUni_AutoDetectionConfiguration: 0,
327 me.PhysicalPathTerminationPointEthernetUni_EthernetLoopbackConfiguration: 0,
328 me.PhysicalPathTerminationPointEthernetUni_AdministrativeState: 0,
329 me.PhysicalPathTerminationPointEthernetUni_OperationalState: 0,
330 me.PhysicalPathTerminationPointEthernetUni_ConfigurationInd: 3,
331 me.PhysicalPathTerminationPointEthernetUni_MaxFrameSize: 1518,
332 me.PhysicalPathTerminationPointEthernetUni_DteOrDceInd: 0,
333 me.PhysicalPathTerminationPointEthernetUni_PauseTime: 0,
334 me.PhysicalPathTerminationPointEthernetUni_BridgedOrIpInd: 2,
335 me.PhysicalPathTerminationPointEthernetUni_Arc: 0,
336 me.PhysicalPathTerminationPointEthernetUni_ArcInterval: 0,
337 me.PhysicalPathTerminationPointEthernetUni_PppoeFilter: 0,
338 me.PhysicalPathTerminationPointEthernetUni_PowerControl: 0,
Elia Battistonac63b112022-01-12 18:40:49 +0100339 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800340 nil,
Elia Battistonac63b112022-01-12 18:40:49 +0100341 })
342 } else {
343 // the remaining ones are pots UNIs, the same is done in onu.go
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000344 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Elia Battistonac63b112022-01-12 18:40:49 +0100345 me.PhysicalPathTerminationPointPotsUniClassID,
346 uniEntityId,
347 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100348 me.PhysicalPathTerminationPointPotsUni_AdministrativeState: 0,
349 me.PhysicalPathTerminationPointPotsUni_Deprecated: 0,
350 me.PhysicalPathTerminationPointPotsUni_Arc: 0,
351 me.PhysicalPathTerminationPointPotsUni_ArcInterval: 0,
352 me.PhysicalPathTerminationPointPotsUni_Impedance: 0,
353 me.PhysicalPathTerminationPointPotsUni_TransmissionPath: 0,
354 me.PhysicalPathTerminationPointPotsUni_RxGain: 0,
355 me.PhysicalPathTerminationPointPotsUni_TxGain: 0,
356 me.PhysicalPathTerminationPointPotsUni_OperationalState: 0,
357 me.PhysicalPathTerminationPointPotsUni_HookState: 0,
358 me.PhysicalPathTerminationPointPotsUni_PotsHoldoverTime: 0,
359 me.PhysicalPathTerminationPointPotsUni_NominalFeedVoltage: 0,
360 me.PhysicalPathTerminationPointPotsUni_LossOfSoftswitch: 0,
Elia Battistonac63b112022-01-12 18:40:49 +0100361 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800362 nil,
Elia Battistonac63b112022-01-12 18:40:49 +0100363 })
364 }
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700365
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000366 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700367 me.UniGClassID,
368 uniEntityId,
369 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100370 me.UniG_AdministrativeState: 0,
371 me.UniG_Deprecated: 0,
372 me.UniG_ManagementCapability: 0,
373 me.UniG_NonOmciManagementIdentifier: 0,
374 me.UniG_RelayAgentOptions: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700375 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800376 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700377 })
378
379 // Downstream Queues (related to PPTP)
380 // 16 priorities queues for each UNI Ports
381 // EntityID = cardHolderSlotID + Uni EntityID (0101)
382 for j := 1; j <= downstreamPriorityQueues; j++ {
383 queueEntityId := EntityID{cardHolderSlotID, byte(j)}
384
385 // we first report the PriorityQueue without any attribute
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000386 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700387 me.PriorityQueueClassID,
388 queueEntityId, //was not reported in the original implementation
389 me.AttributeValueMap{},
Matteo Scandolocfedba42022-02-14 16:08:54 -0800390 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700391 })
392
393 // then we report it with the required attributes
394 // 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.
395 relatedPort := append(uniEntityId, 0x00, byte(j))
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000396 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700397 me.PriorityQueueClassID,
398 queueEntityId, //was not reported in the original implementation
399 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100400 me.PriorityQueue_QueueConfigurationOption: 0,
401 me.PriorityQueue_MaximumQueueSize: 100,
402 me.PriorityQueue_AllocatedQueueSize: 100,
403 me.PriorityQueue_DiscardBlockCounterResetInterval: 0,
404 me.PriorityQueue_ThresholdValueForDiscardedBlocksDueToBufferOverflow: 0,
405 me.PriorityQueue_RelatedPort: relatedPort.ToUint32(),
406 me.PriorityQueue_TrafficSchedulerPointer: 0, //it was hardcoded to 0x0108 in the current implementation
407 me.PriorityQueue_Weight: 1,
408 me.PriorityQueue_BackPressureOperation: 1,
409 me.PriorityQueue_BackPressureTime: 0,
410 me.PriorityQueue_BackPressureOccurQueueThreshold: 0,
411 me.PriorityQueue_BackPressureClearQueueThreshold: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700412 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800413 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700414 })
415 }
416 }
417
418 // T-CONTS and Traffic Schedulers
419 for i := 1; i <= tconts; i++ {
420 tcontEntityId := EntityID{tcontSlotId, byte(i)}
421
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000422 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700423 me.TContClassID,
424 tcontEntityId,
425 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100426 me.TCont_AllocId: 65535,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700427 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800428 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700429 })
430
431 tsEntityId := EntityID{cardHolderSlotID, byte(i)}
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000432 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700433 me.TrafficSchedulerClassID,
434 tsEntityId, //was not reported in the original implementation
435 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100436 me.TrafficScheduler_TContPointer: tcontEntityId.ToUint16(), // was hardcoded to a non-existing t-cont
437 me.TrafficScheduler_TrafficSchedulerPointer: 0,
438 me.TrafficScheduler_Policy: 02,
439 me.TrafficScheduler_PriorityWeight: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700440 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800441 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700442 })
443
444 for j := 1; j <= upstreamPriorityQueues; j++ {
445 queueEntityId := EntityID{tcontSlotId, byte(j)}
446 // Upstream Queues (related to traffic schedulers)
447 // 8 priorities queues per TCONT
448 // EntityID = tcontSlotId + Uni EntityID (8001)
449
450 // we first report the PriorityQueue without any attribute
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000451 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700452 me.PriorityQueueClassID,
453 queueEntityId, //was not reported in the original implementation
454 me.AttributeValueMap{},
Matteo Scandolocfedba42022-02-14 16:08:54 -0800455 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700456 })
457
458 // then we report it with the required attributes
459 // 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.
460 relatedPort := append(tcontEntityId, 0x00, byte(j))
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000461 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700462 me.PriorityQueueClassID,
463 queueEntityId, //was not reported in the original implementation
464 me.AttributeValueMap{
Elia Battiston9bfe1102022-02-03 10:38:03 +0100465 me.PriorityQueue_QueueConfigurationOption: 0,
466 me.PriorityQueue_MaximumQueueSize: 100,
467 me.PriorityQueue_AllocatedQueueSize: 100,
468 me.PriorityQueue_DiscardBlockCounterResetInterval: 0,
469 me.PriorityQueue_ThresholdValueForDiscardedBlocksDueToBufferOverflow: 0,
470 me.PriorityQueue_RelatedPort: relatedPort.ToUint32(),
471 me.PriorityQueue_TrafficSchedulerPointer: tsEntityId.ToUint16(), //it was hardcoded to 0x0108 in the current implementation
472 me.PriorityQueue_Weight: 1,
473 me.PriorityQueue_BackPressureOperation: 1,
474 me.PriorityQueue_BackPressureTime: 0,
475 me.PriorityQueue_BackPressureOccurQueueThreshold: 0,
476 me.PriorityQueue_BackPressureClearQueueThreshold: 0,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700477 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800478 nil,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700479 })
480 }
481 }
482
483 // ONU-2g
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700484
485 onu2g := MibDbEntry{
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700486 me.Onu2GClassID,
487 EntityID{0x00, 0x00},
488 me.AttributeValueMap{
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700489 //me.Onu2G_EquipmentId: 1,
490 //me.Onu2G_OpticalNetworkUnitManagementAndControlChannelOmccVersion: 2,
491 //me.Onu2G_VendorProductCode: 3,
492 //me.Onu2G_SecurityCapability: 4,
493 //me.Onu2G_SecurityMode: 5,
494
Elia Battiston9bfe1102022-02-03 10:38:03 +0100495 me.Onu2G_TotalPriorityQueueNumber: 64,
496 me.Onu2G_TotalTrafficSchedulerNumber: 8,
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700497 me.Onu2G_Deprecated: 1,
498 me.Onu2G_TotalGemPortIdNumber: 8,
499 me.Onu2G_Sysuptime: 6,
500 me.Onu2G_ConnectivityCapability: 127,
501 me.Onu2G_CurrentConnectivityMode: 7,
502 me.Onu2G_QualityOfServiceQosConfigurationFlexibility: 63,
503 me.Onu2G_PriorityQueueScaleFactor: 1,
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700504 },
Matteo Scandolocfedba42022-02-14 16:08:54 -0800505 nil,
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700506 }
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700507
Matteo Scandolocfedba42022-02-14 16:08:54 -0800508 if common.Config.BBSim.InjectOmciUnknownAttributes {
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700509 onu2g = MibDbEntry{
510 me.Onu2GClassID,
511 nil,
512 me.AttributeValueMap{},
513 []byte{129, 41, 46, 10, 0, 2, 0, 0, 1, 1, 0, 0, 7, 253, 0, 64, 8, 1, 0, 8, 0, 0, 0, 6, 0, 127, 7, 0, 63, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 40},
514 }
515 }
516
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000517 mibDb.baselineItems = append(mibDb.baselineItems, onu2g)
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700518
519 if common.Config.BBSim.InjectOmciUnknownMe {
Matteo Scandolocfedba42022-02-14 16:08:54 -0800520 // NOTE the TxID is actually replaced
521 // by SetTxIdInEncodedPacket in CreateMibUploadNextResponse
522 txId := uint16(33066)
523
524 b := make([]byte, 4)
525 binary.BigEndian.PutUint16(b, txId)
526 b[2] = byte(omci.MibUploadNextResponseType)
527 b[3] = byte(omci.BaselineIdent)
528 omciHdr := hex.EncodeToString(b)
529
530 //omciHdr := "00032e0a"
531 msgHdr := "00020000"
Matteo Scandolocfedba42022-02-14 16:08:54 -0800532 trailer := "0000002828ce00e2"
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000533 msg := omciHdr + msgHdr + unknownMePktReportedMeHdr + unknownMePktAttributes + trailer
Matteo Scandolocfedba42022-02-14 16:08:54 -0800534 data, err := hex.DecodeString(msg)
535 if err != nil {
536 omciLogger.Fatal("cannot-create-custom-packet")
537 }
538
539 packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.Lazy)
540
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000541 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandolocfedba42022-02-14 16:08:54 -0800542 me.ClassID(37), // G.988 "Intentionally left blank"
543 nil,
544 me.AttributeValueMap{},
545 packet.Data(),
546 })
547 }
548
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000549 mibDb.NumberOfBaselineCommands = uint16(len(mibDb.baselineItems))
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700550
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000551 // Create extended MIB upload responses
552 omciLayer := &omci.OMCI{
553 TransactionID: 0xFFFF, //to be replaced later on
554 MessageType: omci.MibUploadNextResponseType,
555 DeviceIdentifier: omci.ExtendedIdent,
556 }
557 var i uint16 = 0
558 for i < mibDb.NumberOfBaselineCommands {
559 currentEntry := mibDb.baselineItems[i]
560 for mibDb.baselineItems[i].packet != nil {
561 // Skip any entry with a predefined packet currently used for MEs with unknown ClassID or unknown attributes.
562 // This information will be added later to the last extended response packet
563 i++
564 currentEntry = mibDb.baselineItems[i]
565 }
566 reportedME, meErr := me.LoadManagedEntityDefinition(currentEntry.classId, me.ParamData{
567 EntityID: currentEntry.entityId.ToUint16(),
568 Attributes: currentEntry.params,
569 })
570 if meErr.GetError() != nil {
571 omciLogger.Errorf("Error while generating reportedME %s: %v", currentEntry.classId.String(), meErr.Error())
572 }
573 request := &omci.MibUploadNextResponse{
574 MeBasePacket: omci.MeBasePacket{
575 EntityClass: me.OnuDataClassID,
576 EntityInstance: uint16(0),
577 Extended: true,
578 },
579 ReportedME: *reportedME,
580 AdditionalMEs: make([]me.ManagedEntity, 0),
581 }
582 i++
583 var outgoingPacket []byte
584 var outgoingPacketLen = 0
585 addMeLoop:
586 for outgoingPacketLen <= omci.MaxExtendedLength-omci.MaxBaselineLength && i < mibDb.NumberOfBaselineCommands {
587 currentEntry := mibDb.baselineItems[i]
588 for mibDb.baselineItems[i].packet != nil {
589 // Skip any entry with a predefined packet currently used for MEs with unknown ClassID or unknown attributes.
590 // This information will be added later to the last extended response packet
591 i++
592 if i < mibDb.NumberOfBaselineCommands {
593 currentEntry = mibDb.baselineItems[i]
594 } else {
595 break addMeLoop
596 }
597 }
598 additionalME, meErr := me.LoadManagedEntityDefinition(currentEntry.classId, me.ParamData{
599 EntityID: currentEntry.entityId.ToUint16(),
600 Attributes: currentEntry.params,
601 })
602 if meErr.GetError() != nil {
603 omciLogger.Errorf("Error while generating additionalME %s: %v", currentEntry.classId.String(), meErr.Error())
604 }
605 request.AdditionalMEs = append(request.AdditionalMEs, *additionalME)
606
607 var options gopacket.SerializeOptions
608 options.FixLengths = true
609
610 buffer := gopacket.NewSerializeBuffer()
611 omciErr := gopacket.SerializeLayers(buffer, options, omciLayer, request)
612 if omciErr != nil {
613 omciLogger.Errorf("Error while serializing generating additionalME %s: %v", currentEntry.classId.String(), omciErr)
614 }
615 outgoingPacket = buffer.Bytes()
616 outgoingPacketLen = len(outgoingPacket)
617 i++
618 }
619 mibDb.extendedResponses = append(mibDb.extendedResponses, outgoingPacket)
620 mibDb.NumberOfExtendedCommands = uint16(len(mibDb.extendedResponses))
621
622 outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
623 omciLogger.Debugf("Extended MIB upload response respNo: %d length: %d string: %s", mibDb.NumberOfExtendedCommands, outgoingPacketLen, outgoingPacketString)
624 }
625 // Currently, there is enough space in the last extended response to add potential MEs with unknown ClassID or unknown attributes, if requested.
626 if common.Config.BBSim.InjectOmciUnknownMe {
627 var err error
628 mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], err = AppendAdditionalMEs(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], unknownMePktReportedMeHdr, unknownMePktAttributes)
629 if err != nil {
630 omciLogger.Fatal(err)
631 } else {
632 outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
633 omciLogger.Debugf("Reponse with unknown ME added: %s", outgoingPacketString)
634 }
635 }
636 if common.Config.BBSim.InjectOmciUnknownAttributes {
637 var err error
638 mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], err = AppendAdditionalMEs(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], unknownAttribPktReportedMeHdr, unknownAttribPktAttributes)
639 if err != nil {
640 omciLogger.Fatal(err)
641 } else {
642 outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
643 omciLogger.Debugf("Reponse with unknown attributes added: %s", outgoingPacketString)
644 }
645 }
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700646 return &mibDb, nil
647}
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000648
649func AppendAdditionalMEs(srcSlice []byte, reportedMeHdr string, attributes string) ([]byte, error) {
650 attribBytes, err := hex.DecodeString(attributes)
651 if err != nil {
652 return nil, fmt.Errorf("cannot-decode-attributes-string")
653 }
654 attribBytesLen := len(attribBytes)
655 attribBytesLenStr := fmt.Sprintf("%04X", attribBytesLen)
656 msg := attribBytesLenStr + reportedMeHdr + attributes
657 data, err := hex.DecodeString(msg)
658 if err != nil {
659 return nil, fmt.Errorf("cannot-decode-attributes")
660 }
661 dstSlice := make([]byte, len(srcSlice))
662 copy(dstSlice, srcSlice)
663 dstSlice = append(dstSlice[:], data[:]...)
664 messageContentsLen := binary.BigEndian.Uint16(dstSlice[extRespMsgContentsLenStart:extRespMsgContentsLenEnd])
665 dataLen := len(data)
666 newMessageContentsLen := messageContentsLen + uint16(dataLen)
667 newLenSlice := make([]byte, 2)
668 binary.BigEndian.PutUint16(newLenSlice, newMessageContentsLen)
669 copy(dstSlice[extRespMsgContentsLenStart:extRespMsgContentsLenEnd], newLenSlice[0:2])
670 return dstSlice, nil
671}