blob: 97213ca0eee7e81a87e6332683c3c850edf2f0c8 [file] [log] [blame]
Matteo Scandoloef4e8f82021-05-17 11:20:49 -07001/*
Joey Armstrong2c039362024-02-04 18:51:52 -05002 * Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors
Matteo Scandoloef4e8f82021-05-17 11:20:49 -07003
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"
Holger Hildebrandt78403782022-05-13 10:59:31 +000055 unknownAttribPktAttributes string = "00400801000800000006007F07003F0001000100010001000000"
Holger Hildebrandt236e3742022-05-04 14:07:27 +000056 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
Holger Hildebrandt01f92ce2022-12-20 09:33:57 +000099 upstreamPriorityQueues = 8 // Number of queues for each T-CONT
100 downstreamPriorityQueues = 8 // Number of queues for each PPTP
101 tconts = 8 // NOTE will we ever need to configure this?
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700102 // 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)
Holger Hildebrandt01f92ce2022-12-20 09:33:57 +0000380 // downstreamPriorityQueues for each UNI Port
381 // EntityID = MSB: cardHolderSlotID, LSB: uniPortNo<<4 + prio
382 for j := 0; j < downstreamPriorityQueues; j++ {
383 queueEntityId := EntityID{cardHolderSlotID, byte(i<<4 + j)}
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700384
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
Holger Hildebrandt01f92ce2022-12-20 09:33:57 +0000444 for j := 0; j < upstreamPriorityQueues; j++ {
445 queueEntityId := EntityID{tcontSlotId, byte(i<<4 + j)}
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700446 // Upstream Queues (related to traffic schedulers)
Holger Hildebrandt01f92ce2022-12-20 09:33:57 +0000447 // upstreamPriorityQueues per TCONT
448 // EntityID = MSB: tcontSlotId, LSB: tcontNo<<4 + prio
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700449
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 {
Holger Hildebrandt78403782022-05-13 10:59:31 +0000509 // NOTE the TxID is actually replaced
510 // by SetTxIdInEncodedPacket in CreateMibUploadNextResponse
511 txId := uint16(33066)
512
513 b := make([]byte, 4)
514 binary.BigEndian.PutUint16(b, txId)
515 b[2] = byte(omci.MibUploadNextResponseType)
516 b[3] = byte(omci.BaselineIdent)
517 omciHdr := hex.EncodeToString(b)
518
519 //omciHdr := "00032e0a"
520 msgHdr := "00020000"
521 trailer := "0000002828ce00e2"
522
523 msg := omciHdr + msgHdr + unknownAttribPktReportedMeHdr + unknownAttribPktAttributes + trailer
524 data, err := hex.DecodeString(msg)
525 if err != nil {
526 omciLogger.Fatal("cannot-create-custom-packet")
527 }
528 packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.Lazy)
529
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700530 onu2g = MibDbEntry{
531 me.Onu2GClassID,
532 nil,
533 me.AttributeValueMap{},
Holger Hildebrandt78403782022-05-13 10:59:31 +0000534 packet.Data(),
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700535 }
536 }
537
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000538 mibDb.baselineItems = append(mibDb.baselineItems, onu2g)
Matteo Scandolo7011fc92022-03-16 15:50:15 -0700539
540 if common.Config.BBSim.InjectOmciUnknownMe {
Matteo Scandolocfedba42022-02-14 16:08:54 -0800541 // NOTE the TxID is actually replaced
542 // by SetTxIdInEncodedPacket in CreateMibUploadNextResponse
543 txId := uint16(33066)
544
545 b := make([]byte, 4)
546 binary.BigEndian.PutUint16(b, txId)
547 b[2] = byte(omci.MibUploadNextResponseType)
548 b[3] = byte(omci.BaselineIdent)
549 omciHdr := hex.EncodeToString(b)
550
551 //omciHdr := "00032e0a"
552 msgHdr := "00020000"
Matteo Scandolocfedba42022-02-14 16:08:54 -0800553 trailer := "0000002828ce00e2"
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000554 msg := omciHdr + msgHdr + unknownMePktReportedMeHdr + unknownMePktAttributes + trailer
Matteo Scandolocfedba42022-02-14 16:08:54 -0800555 data, err := hex.DecodeString(msg)
556 if err != nil {
557 omciLogger.Fatal("cannot-create-custom-packet")
558 }
559
560 packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.Lazy)
561
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000562 mibDb.baselineItems = append(mibDb.baselineItems, MibDbEntry{
Matteo Scandolocfedba42022-02-14 16:08:54 -0800563 me.ClassID(37), // G.988 "Intentionally left blank"
564 nil,
565 me.AttributeValueMap{},
566 packet.Data(),
567 })
568 }
569
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000570 mibDb.NumberOfBaselineCommands = uint16(len(mibDb.baselineItems))
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700571
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000572 // Create extended MIB upload responses
573 omciLayer := &omci.OMCI{
574 TransactionID: 0xFFFF, //to be replaced later on
575 MessageType: omci.MibUploadNextResponseType,
576 DeviceIdentifier: omci.ExtendedIdent,
577 }
578 var i uint16 = 0
579 for i < mibDb.NumberOfBaselineCommands {
580 currentEntry := mibDb.baselineItems[i]
581 for mibDb.baselineItems[i].packet != nil {
582 // Skip any entry with a predefined packet currently used for MEs with unknown ClassID or unknown attributes.
583 // This information will be added later to the last extended response packet
584 i++
585 currentEntry = mibDb.baselineItems[i]
586 }
587 reportedME, meErr := me.LoadManagedEntityDefinition(currentEntry.classId, me.ParamData{
588 EntityID: currentEntry.entityId.ToUint16(),
589 Attributes: currentEntry.params,
590 })
591 if meErr.GetError() != nil {
592 omciLogger.Errorf("Error while generating reportedME %s: %v", currentEntry.classId.String(), meErr.Error())
593 }
594 request := &omci.MibUploadNextResponse{
595 MeBasePacket: omci.MeBasePacket{
596 EntityClass: me.OnuDataClassID,
597 EntityInstance: uint16(0),
598 Extended: true,
599 },
600 ReportedME: *reportedME,
601 AdditionalMEs: make([]me.ManagedEntity, 0),
602 }
603 i++
604 var outgoingPacket []byte
605 var outgoingPacketLen = 0
606 addMeLoop:
607 for outgoingPacketLen <= omci.MaxExtendedLength-omci.MaxBaselineLength && i < mibDb.NumberOfBaselineCommands {
608 currentEntry := mibDb.baselineItems[i]
609 for mibDb.baselineItems[i].packet != nil {
610 // Skip any entry with a predefined packet currently used for MEs with unknown ClassID or unknown attributes.
611 // This information will be added later to the last extended response packet
612 i++
613 if i < mibDb.NumberOfBaselineCommands {
614 currentEntry = mibDb.baselineItems[i]
615 } else {
616 break addMeLoop
617 }
618 }
619 additionalME, meErr := me.LoadManagedEntityDefinition(currentEntry.classId, me.ParamData{
620 EntityID: currentEntry.entityId.ToUint16(),
621 Attributes: currentEntry.params,
622 })
623 if meErr.GetError() != nil {
624 omciLogger.Errorf("Error while generating additionalME %s: %v", currentEntry.classId.String(), meErr.Error())
625 }
626 request.AdditionalMEs = append(request.AdditionalMEs, *additionalME)
627
628 var options gopacket.SerializeOptions
629 options.FixLengths = true
630
631 buffer := gopacket.NewSerializeBuffer()
632 omciErr := gopacket.SerializeLayers(buffer, options, omciLayer, request)
633 if omciErr != nil {
634 omciLogger.Errorf("Error while serializing generating additionalME %s: %v", currentEntry.classId.String(), omciErr)
635 }
636 outgoingPacket = buffer.Bytes()
637 outgoingPacketLen = len(outgoingPacket)
638 i++
639 }
640 mibDb.extendedResponses = append(mibDb.extendedResponses, outgoingPacket)
641 mibDb.NumberOfExtendedCommands = uint16(len(mibDb.extendedResponses))
642
643 outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
644 omciLogger.Debugf("Extended MIB upload response respNo: %d length: %d string: %s", mibDb.NumberOfExtendedCommands, outgoingPacketLen, outgoingPacketString)
645 }
646 // Currently, there is enough space in the last extended response to add potential MEs with unknown ClassID or unknown attributes, if requested.
647 if common.Config.BBSim.InjectOmciUnknownMe {
648 var err error
649 mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], err = AppendAdditionalMEs(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], unknownMePktReportedMeHdr, unknownMePktAttributes)
650 if err != nil {
651 omciLogger.Fatal(err)
652 } else {
653 outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
654 omciLogger.Debugf("Reponse with unknown ME added: %s", outgoingPacketString)
655 }
656 }
657 if common.Config.BBSim.InjectOmciUnknownAttributes {
658 var err error
659 mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], err = AppendAdditionalMEs(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1], unknownAttribPktReportedMeHdr, unknownAttribPktAttributes)
660 if err != nil {
661 omciLogger.Fatal(err)
662 } else {
663 outgoingPacketString := strings.ToLower(hex.EncodeToString(mibDb.extendedResponses[mibDb.NumberOfExtendedCommands-1]))
664 omciLogger.Debugf("Reponse with unknown attributes added: %s", outgoingPacketString)
665 }
666 }
Matteo Scandoloef4e8f82021-05-17 11:20:49 -0700667 return &mibDb, nil
668}
Holger Hildebrandt236e3742022-05-04 14:07:27 +0000669
670func AppendAdditionalMEs(srcSlice []byte, reportedMeHdr string, attributes string) ([]byte, error) {
671 attribBytes, err := hex.DecodeString(attributes)
672 if err != nil {
673 return nil, fmt.Errorf("cannot-decode-attributes-string")
674 }
675 attribBytesLen := len(attribBytes)
676 attribBytesLenStr := fmt.Sprintf("%04X", attribBytesLen)
677 msg := attribBytesLenStr + reportedMeHdr + attributes
678 data, err := hex.DecodeString(msg)
679 if err != nil {
680 return nil, fmt.Errorf("cannot-decode-attributes")
681 }
682 dstSlice := make([]byte, len(srcSlice))
683 copy(dstSlice, srcSlice)
684 dstSlice = append(dstSlice[:], data[:]...)
685 messageContentsLen := binary.BigEndian.Uint16(dstSlice[extRespMsgContentsLenStart:extRespMsgContentsLenEnd])
686 dataLen := len(data)
687 newMessageContentsLen := messageContentsLen + uint16(dataLen)
688 newLenSlice := make([]byte, 2)
689 binary.BigEndian.PutUint16(newLenSlice, newMessageContentsLen)
690 copy(dstSlice[extRespMsgContentsLenStart:extRespMsgContentsLenEnd], newLenSlice[0:2])
691 return dstSlice, nil
692}