blob: 482c0b86eeed0d83584d28af3644b85a3b7c419a [file] [log] [blame]
Chip Boling934e1052021-09-27 15:12:06 -05001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
3 * Copyright 2020-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package omci_test
19
20import (
21 "github.com/google/gopacket"
Andrea Campanellae0cd8232021-10-15 15:10:23 +020022 . "github.com/opencord/omci-lib-go/v2"
23 me "github.com/opencord/omci-lib-go/v2/generated"
Chip Boling934e1052021-09-27 15:12:06 -050024 "github.com/stretchr/testify/assert"
25 "testing"
26)
27
28var relaxDecodeSupportedResponses = []me.MsgType{
29 // me.Get,
30 me.MibUploadNext,
31}
32
33func canRelax(arr []me.MsgType, msgType me.MsgType) bool {
34 for _, item := range arr {
35 if item == msgType {
36 return true
37 }
38 }
39 return false
40}
41
42func TestAllTypesRelaxedDecodeSupport(t *testing.T) {
43 // Requests (none are supported yet)
44 for _, msgType := range allMsgTypes {
45 assert.Error(t, me.SetRelaxedDecode(msgType, true, true))
46 assert.False(t, me.GetRelaxedDecode(msgType, true))
47 }
48 // Responses (only a couple are supported at this time)
49 for _, msgType := range allMsgTypes {
50
51 if canRelax(relaxDecodeSupportedResponses, msgType) {
52 // Default is True if it is supported
53 assert.True(t, me.GetRelaxedDecode(msgType, false))
54
55 // Set False
56 assert.NoError(t, me.SetRelaxedDecode(msgType, false, false))
57 assert.False(t, me.GetRelaxedDecode(msgType, false))
58
59 // Set back to True
60 assert.NoError(t, me.SetRelaxedDecode(msgType, false, true))
61 assert.True(t, me.GetRelaxedDecode(msgType, false))
62 } else {
63 // Default is False
64 assert.False(t, me.GetRelaxedDecode(msgType, false))
65 assert.Error(t, me.SetRelaxedDecode(msgType, false, true))
66 assert.Error(t, me.SetRelaxedDecode(msgType, false, false))
67 }
68 }
69}
70
71// TestMibUploadNextResponseRelaxedDecode will decode a frame with 'new' unknown
72// attributes at the end (fake ones for this test) and should fail. Then it will
73// enable relax decode and should be able to successfully decode the parts that
74// it knows and have access to the rest.
75func TestMibUploadNextResponseRelaxedDecode(t *testing.T) {
76 // Test msg has OLT-G ME that normally only has 4 attributes defined. Since several are
77 // pretty big and would normally take at least 3 MIB upload next frames. So in
78 // this one it has the last 'known' one, plus two new ones.
79 extraTrailer := "123400001234000000000000"
80 goodAttribute := "123456780a090807060504030201"
81 mibUploadNextLayer := "00020000008300001c00" + goodAttribute + extraTrailer
82 goodMessage := "02862e0a" + mibUploadNextLayer + "00000028"
83
84 data, err := stringToPacket(goodMessage)
85 assert.NoError(t, err)
86
87 extraTrailerData, _ := stringToPacket(extraTrailer)
88 assert.NotNil(t, extraTrailerData)
89
90 mibUploadNextLayerData, _ := stringToPacket(mibUploadNextLayer)
91 assert.NotNil(t, mibUploadNextLayerData)
92
93 goodAttributeData, _ := stringToPacket(goodAttribute)
94 assert.NotNil(t, goodAttributeData)
95
96 // Make sure relaxed decode is disabled
97 assert.NoError(t, me.SetRelaxedDecode(me.MibUploadNext, false, false))
98 assert.False(t, me.GetRelaxedDecode(me.MibUploadNext, false))
99
100 // Should get a packet but there should also be an error layer after the OMCI layer
101 packet := gopacket.NewPacket(data, LayerTypeOMCI, gopacket.NoCopy)
102 assert.NotNil(t, packet)
103
104 omciLayer := packet.Layer(LayerTypeOMCI)
105 assert.NotNil(t, omciLayer)
106
107 omciMsg, ok := omciLayer.(*OMCI)
108 assert.True(t, ok)
109 assert.NotNil(t, omciMsg)
110
111 assert.Equal(t, LayerTypeOMCI, omciMsg.LayerType())
112 assert.Equal(t, LayerTypeOMCI, omciMsg.CanDecode())
113 assert.Equal(t, LayerTypeMibUploadNextResponse, omciMsg.NextLayerType())
114 assert.Equal(t, uint16(0x0286), omciMsg.TransactionID)
115 assert.Equal(t, MibUploadNextResponseType, omciMsg.MessageType)
116 assert.Equal(t, BaselineIdent, omciMsg.DeviceIdentifier)
117 assert.Equal(t, uint16(40), omciMsg.Length)
118
119 // Without relaxed decode, the MIB Upload Next Response cannot be decoded further
120 // but can get the error layer and it's contents (which is the entire MIB Upload Response data
121 msgLayer := packet.Layer(LayerTypeMibUploadNextResponse)
122 assert.Nil(t, msgLayer)
123
124 errLayer := packet.Layer(gopacket.LayerTypeDecodeFailure)
125 assert.NotNil(t, errLayer)
126 assert.Nil(t, errLayer.LayerPayload())
127 errContents := errLayer.LayerContents()
128 assert.NotNil(t, errContents)
129 assert.Equal(t, mibUploadNextLayerData, errContents)
130
131 ////////////////////////////////////////////////////////////////////////////
132 ////////////////////////////////////////////////////////////////////////////
133 ////////////////////////////////////////////////////////////////////////////
134 // Now turn on relaxed decode and you can now go further into the packet
135 assert.NoError(t, me.SetRelaxedDecode(me.MibUploadNext, false, true))
136 assert.True(t, me.GetRelaxedDecode(me.MibUploadNext, false))
137
138 packet = gopacket.NewPacket(data, LayerTypeOMCI, gopacket.NoCopy)
139 assert.NotNil(t, packet)
140
141 omciLayer = packet.Layer(LayerTypeOMCI)
142 assert.NotNil(t, omciLayer)
143
144 omciMsg, ok = omciLayer.(*OMCI)
145 assert.True(t, ok)
146 assert.NotNil(t, omciMsg)
147
148 // Skipping the test of OMCI layer values. It is same as above
149 //
150 // Get that message layer that has data that could be decoded. If relaxed decode was
151 // not enable, this would have returned a 'nil' value
152 msgLayer = packet.Layer(LayerTypeMibUploadNextResponse)
153 assert.NotNil(t, msgLayer)
154
155 response, ok2 := msgLayer.(*MibUploadNextResponse)
156 assert.True(t, ok2)
157 assert.NotNil(t, response)
158 assert.Equal(t, LayerTypeMibUploadNextResponse, response.LayerType())
159 assert.Equal(t, LayerTypeMibUploadNextResponse, response.CanDecode())
160 assert.Equal(t, me.OltGClassID, response.ReportedME.GetClassID())
161 assert.Equal(t, uint16(0), response.ReportedME.GetEntityID())
162
163 // The attribute mask decoded at this layer only contains the attributes we
164 // could successfully decode
165 assert.Equal(t, uint16(0x1000), response.ReportedME.GetAttributeMask())
166
167 attributes := me.AttributeValueMap{
168 "TimeOfDayInformation": goodAttributeData, // NOTE: This is binary data for the comparison below
169 }
170 for name, value := range attributes {
171 pktValue, err := response.ReportedME.GetAttribute(name)
172 assert.Nil(t, err)
173 assert.Equal(t, pktValue, value)
174 }
175 assert.Nil(t, response.AdditionalMEs)
176
177 ////////////////////////////////////////////////////////////////////////////
178 // Here is the new functionality. In order to store both a well decoded
179 // MIB UPLOAD NEXT response layer, along with a relaxed decode error, the
180 // layer addition has to be done in a specific way and an error returned.
181 //
182 // Note that the previous line (below) worked in the code above
183 //
184 // response, ok2 := msgLayer.(*MibUploadNextResponse)
185 //
186 // If you did not care about what the relaxed decode found out, just proceed
187 // on as normal. However, since you enabled relaxed decoding of the unknown
188 // attributes, here is where you can pull extra information from.
189 //
190 // The first way is to just try and see if that error layer was decoded
191 //
192 // if unknownAttrLayer = packet.Layer(LayerTypeUnknownAttributes); unknownAttrLayer != nil {
193 // log.warning(HEY! Got some unknown attributes to this ME: '%v', unknownAttrLayer)
194 //
195 // unknownAttributes, ok2 := msgLayer.(*UnknownAttributes); ok {
196 // //
197 // // Since some extended messages can actually return multiple managed entities,
198 // // all ME's with unknown attributes need to be uniquely identified
199 // //
200 // for _, unknown := range unknownAttibutes.Attributes {
201 // whichME := unknown.EntityClass // ClassID
202 // whichInst := unknown.EntityInstance // uint16
203 // unknownMask := unknown.AttributeMask // uint16
204 // unknownBlob := unknown.Attributes // []byte
205 //
206 // // Unless this is the extended message set and only a single attribute
207 // // mask bit is set, you really do not know what possible kind of data
208 // // type the attribute is...
209 // }
210 // }
211 // }
212 /////////////////////////////////////
213 assert.NotEqual(t, gopacket.LayerTypePayload, response.NextLayerType())
214 assert.Equal(t, LayerTypeUnknownAttributes, response.NextLayerType())
215
216 unknownAttrLayer := packet.Layer(LayerTypeUnknownAttributes)
217 assert.NotNil(t, unknownAttrLayer)
218
219 unknown, ok2 := unknownAttrLayer.(*UnknownAttributes)
220 assert.True(t, ok2)
221 assert.NotNil(t, unknown)
222 assert.Equal(t, LayerTypeUnknownAttributes, unknown.LayerType())
223 assert.Equal(t, LayerTypeUnknownAttributes, unknown.CanDecode())
224 assert.Equal(t, gopacket.LayerTypeZero, unknown.NextLayerType())
225
226 // Only one Managed entity was in this response and had a bad attribute
227 assert.Equal(t, 1, len(unknown.Attributes))
228 assert.Equal(t, me.OltGClassID, unknown.Attributes[0].EntityClass)
229 assert.Equal(t, uint16(0), unknown.Attributes[0].EntityInstance)
230 assert.Equal(t, uint16(0x0c00), unknown.Attributes[0].AttributeMask)
231 assert.Equal(t, extraTrailerData, unknown.Attributes[0].AttributeData)
232}
233
234// TestMibUploadNextResponseExtendedRelaxedDecode is the extended message
235// set test of the test above (just one Managed Entity)
236func TestMibUploadNextResponseExtendedRelaxedDecode(t *testing.T) {
237 // Test msg has OLT-G ME that normally only has 4 attributes defined. Since several are
238 // pretty big and would normally take at least 3 MIB upload next frames. So in
239 // this one it has the last 'known' one, plus two new ones.
240 extraTrailer := "123400001234" // 6 octets
241 goodAttribute := "123456780a090807060504030201" // 14 octets
242 mibUploadNextLayer := "00020000" + "001c" +
243 "0014" +
244 "008300001c00" + // 6 octets
245 goodAttribute + extraTrailer // 14 + 6 octets
246 goodMessage := "02862e0b" + mibUploadNextLayer
247
248 data, err := stringToPacket(goodMessage)
249 assert.NoError(t, err)
250
251 extraTrailerData, _ := stringToPacket(extraTrailer)
252 assert.NotNil(t, extraTrailerData)
253
254 mibUploadNextLayerData, _ := stringToPacket(mibUploadNextLayer)
255 assert.NotNil(t, mibUploadNextLayerData)
256
257 goodAttributeData, _ := stringToPacket(goodAttribute)
258 assert.NotNil(t, goodAttributeData)
259
260 // Make sure relaxed decode is disabled
261 assert.NoError(t, me.SetRelaxedDecode(me.MibUploadNext, false, false))
262 assert.False(t, me.GetRelaxedDecode(me.MibUploadNext, false))
263
264 // Should get a packet but there should also be an error layer after the OMCI layer
265 packet := gopacket.NewPacket(data, LayerTypeOMCI, gopacket.NoCopy)
266 assert.NotNil(t, packet)
267
268 omciLayer := packet.Layer(LayerTypeOMCI)
269 assert.NotNil(t, omciLayer)
270
271 omciMsg, ok := omciLayer.(*OMCI)
272 assert.True(t, ok)
273 assert.NotNil(t, omciMsg)
274
275 assert.Equal(t, LayerTypeOMCI, omciMsg.LayerType())
276 assert.Equal(t, LayerTypeOMCI, omciMsg.CanDecode())
277 assert.Equal(t, LayerTypeMibUploadNextResponse, omciMsg.NextLayerType())
278 assert.Equal(t, uint16(0x0286), omciMsg.TransactionID)
279 assert.Equal(t, MibUploadNextResponseType, omciMsg.MessageType)
280 assert.Equal(t, ExtendedIdent, omciMsg.DeviceIdentifier)
281 assert.Equal(t, uint16(28), omciMsg.Length)
282
283 // Without relaxed decode, the MIB Upload Next Response cannot be decoded further
284 // but can get the error layer and it's contents (which is the entire MIB Upload Response data
285 msgLayer := packet.Layer(LayerTypeMibUploadNextResponse)
286 assert.Nil(t, msgLayer)
287
288 errLayer := packet.Layer(gopacket.LayerTypeDecodeFailure)
289 assert.NotNil(t, errLayer)
290 assert.Nil(t, errLayer.LayerPayload())
291 errContents := errLayer.LayerContents()
292 assert.NotNil(t, errContents)
293 assert.Equal(t, mibUploadNextLayerData, errContents)
294
295 ////////////////////////////////////////////////////////////////////////////
296 ////////////////////////////////////////////////////////////////////////////
297 ////////////////////////////////////////////////////////////////////////////
298 // Now turn on relaxed decode and you can now go further into the packet
299 assert.NoError(t, me.SetRelaxedDecode(me.MibUploadNext, false, true))
300 assert.True(t, me.GetRelaxedDecode(me.MibUploadNext, false))
301
302 packet = gopacket.NewPacket(data, LayerTypeOMCI, gopacket.NoCopy)
303 assert.NotNil(t, packet)
304
305 omciLayer = packet.Layer(LayerTypeOMCI)
306 assert.NotNil(t, omciLayer)
307
308 omciMsg, ok = omciLayer.(*OMCI)
309 assert.True(t, ok)
310 assert.NotNil(t, omciMsg)
311
312 // Skipping the test of OMCI layer values. It is same as above
313 //
314 // Get that message layer that has data that could be decoded
315 msgLayer = packet.Layer(LayerTypeMibUploadNextResponse)
316 assert.NotNil(t, msgLayer)
317
318 response, ok2 := msgLayer.(*MibUploadNextResponse)
319 assert.True(t, ok2)
320 assert.NotNil(t, response)
321 assert.Equal(t, LayerTypeMibUploadNextResponse, response.LayerType())
322 assert.Equal(t, LayerTypeMibUploadNextResponse, response.CanDecode())
323 assert.Equal(t, me.OltGClassID, response.ReportedME.GetClassID())
324 assert.Equal(t, uint16(0), response.ReportedME.GetEntityID())
325
326 // The attribute mask decoded at this layer only contains the attributes we
327 // could successfully decode
328 assert.Equal(t, uint16(0x1000), response.ReportedME.GetAttributeMask())
329
330 attributes := me.AttributeValueMap{
331 "TimeOfDayInformation": goodAttributeData, // NOTE: This is binary data for the comparison below
332 }
333 for name, value := range attributes {
334 pktValue, err := response.ReportedME.GetAttribute(name)
335 assert.Nil(t, err)
336 assert.Equal(t, pktValue, value)
337 }
338 ////////////////////////////////////////////////////////////////////////////
339 // Here is the new functionality. In order to store both a well decoded
340 // MIB UPLOAD NEXT response layer, along with a relaxed decode error, the
341 // layer addition has to be done in a specific way and an error returned.
342 //
343 // Note that the previous line (below) worked in the code above
344 //
345 // response, ok2 := msgLayer.(*MibUploadNextResponse)
346 //
347 // If you did not care about what the relaxed decode found out, just proceed
348 // on as normal. However, since you enabled relaxed decoding of the unknown
349 // attributes, here is where you can pull extra information from.
350 //
351 // The first way is to just try and see if that error layer was decoded
352 //
353 // if unknownAttrLayer = packet.Layer(LayerTypeUnknownAttributes); unknownAttrLayer != nil {
354 // log.warning(HEY! Got some unknown attributes to this ME: '%v', unknownAttrLayer)
355 //
356 // unknownAttributes, ok2 := msgLayer.(*UnknownAttributes); ok {
357 // //
358 // // Since some extended messages can actually return multiple managed entities,
359 // // all ME's with unknown attributes need to be uniquely identified
360 // //
361 // for _, unknown := range unknownAttibutes.Attributes {
362 // whichME := unknown.EntityClass // ClassID
363 // whichInst := unknown.EntityInstance // uint16
364 // unknownMask := unknown.AttributeMask // uint16
365 // unknownBlob := unknown.Attributes // []byte
366 //
367 // // Unless this is the extended message set and only a single attribute
368 // // mask bit is set, you really do not know what possible kind of data
369 // // type the attribute is...
370 // }
371 // }
372 // }
373 /////////////////////////////////////
374 assert.NotEqual(t, gopacket.LayerTypePayload, response.NextLayerType())
375 assert.Equal(t, LayerTypeUnknownAttributes, response.NextLayerType())
376
377 unknownAttrLayer := packet.Layer(LayerTypeUnknownAttributes)
378 assert.NotNil(t, unknownAttrLayer)
379
380 unknown, ok2 := unknownAttrLayer.(*UnknownAttributes)
381 assert.True(t, ok2)
382 assert.NotNil(t, unknown)
383 assert.Equal(t, LayerTypeUnknownAttributes, unknown.LayerType())
384 assert.Equal(t, LayerTypeUnknownAttributes, unknown.CanDecode())
385 assert.Equal(t, gopacket.LayerTypeZero, unknown.NextLayerType())
386
387 // Only one Managed entity was in this response and had a bad attribute
388 assert.Equal(t, 1, len(unknown.Attributes))
389 assert.Equal(t, me.OltGClassID, unknown.Attributes[0].EntityClass)
390 assert.Equal(t, uint16(0), unknown.Attributes[0].EntityInstance)
391 assert.Equal(t, uint16(0x0c00), unknown.Attributes[0].AttributeMask)
392 assert.Equal(t, uint16(0x0c00), unknown.Attributes[0].AttributeMask)
393 assert.Equal(t, extraTrailerData, unknown.Attributes[0].AttributeData)
394
395}
396
397// TestMibUploadNextResponseExtendedRelaxedDecode is the extended message
398// set test of the test above (with two Managed Entity where both have bad attributes)
399func TestMibUploadNextResponseExtendedRelaxedDecodeTwoMEs(t *testing.T) {
400 // Test msg has OLT-G ME that normally only has 4 attributes defined. Since several are
401 // pretty big and would normally take at least 3 MIB upload next frames. So in
402 // this one it has the last 'known' one, plus two new ones.
403 extraTrailer1 := "123400001234" // 6 octets
404 extraTrailer2 := "432100004321" // 6 octets
405 goodAttribute := "123456780a090807060504030201" // 14 octets
406 mibUploadNextLayer := "00020000" + "0038" +
407 "0014" +
408 "008300001c00" + // 6 octets
409 goodAttribute + extraTrailer1 + // 14 + 6 octets
410 "0014" +
411 "008300011c00" + // 6 octets (entity ID 1 which is invalid for OLT-g, but this is a test)
412 goodAttribute + extraTrailer2 // 14 + 6 octets
413
414 goodMessage := "02862e0b" + mibUploadNextLayer
415
416 data, err := stringToPacket(goodMessage)
417 assert.NoError(t, err)
418
419 extraTrailerData1, _ := stringToPacket(extraTrailer1)
420 assert.NotNil(t, extraTrailerData1)
421 extraTrailerData2, _ := stringToPacket(extraTrailer2)
422 assert.NotNil(t, extraTrailerData2)
423
424 mibUploadNextLayerData, _ := stringToPacket(mibUploadNextLayer)
425 assert.NotNil(t, mibUploadNextLayerData)
426
427 goodAttributeData, _ := stringToPacket(goodAttribute)
428 assert.NotNil(t, goodAttributeData)
429
430 // Make sure relaxed decode is disabled
431 assert.NoError(t, me.SetRelaxedDecode(me.MibUploadNext, false, false))
432 assert.False(t, me.GetRelaxedDecode(me.MibUploadNext, false))
433
434 // Should get a packet but there should also be an error layer after the OMCI layer
435 packet := gopacket.NewPacket(data, LayerTypeOMCI, gopacket.NoCopy)
436 assert.NotNil(t, packet)
437
438 omciLayer := packet.Layer(LayerTypeOMCI)
439 assert.NotNil(t, omciLayer)
440
441 omciMsg, ok := omciLayer.(*OMCI)
442 assert.True(t, ok)
443 assert.NotNil(t, omciMsg)
444
445 assert.Equal(t, LayerTypeOMCI, omciMsg.LayerType())
446 assert.Equal(t, LayerTypeOMCI, omciMsg.CanDecode())
447 assert.Equal(t, LayerTypeMibUploadNextResponse, omciMsg.NextLayerType())
448 assert.Equal(t, uint16(0x0286), omciMsg.TransactionID)
449 assert.Equal(t, MibUploadNextResponseType, omciMsg.MessageType)
450 assert.Equal(t, ExtendedIdent, omciMsg.DeviceIdentifier)
451 assert.Equal(t, uint16(56), omciMsg.Length)
452
453 // Without relaxed decode, the MIB Upload Next Response cannot be decoded further
454 // but can get the error layer and it's contents (which is the entire MIB Upload Response data
455 msgLayer := packet.Layer(LayerTypeMibUploadNextResponse)
456 assert.Nil(t, msgLayer)
457
458 errLayer := packet.Layer(gopacket.LayerTypeDecodeFailure)
459 assert.NotNil(t, errLayer)
460 assert.Nil(t, errLayer.LayerPayload())
461 errContents := errLayer.LayerContents()
462 assert.NotNil(t, errContents)
463 assert.Equal(t, mibUploadNextLayerData, errContents)
464
465 ////////////////////////////////////////////////////////////////////////////
466 ////////////////////////////////////////////////////////////////////////////
467 ////////////////////////////////////////////////////////////////////////////
468 // Now turn on relaxed decode and you can now go further into the packet
469 assert.NoError(t, me.SetRelaxedDecode(me.MibUploadNext, false, true))
470 assert.True(t, me.GetRelaxedDecode(me.MibUploadNext, false))
471 packet = gopacket.NewPacket(data, LayerTypeOMCI, gopacket.NoCopy)
472 assert.NotNil(t, packet)
473
474 omciLayer = packet.Layer(LayerTypeOMCI)
475 assert.NotNil(t, omciLayer)
476
477 omciMsg, ok = omciLayer.(*OMCI)
478 assert.True(t, ok)
479 assert.NotNil(t, omciMsg)
480
481 // Skipping the test of OMCI layer values. It is same as above
482 //
483 // Get that message layer that has data that could be decoded
484 msgLayer = packet.Layer(LayerTypeMibUploadNextResponse)
485 assert.NotNil(t, msgLayer)
486
487 response, ok2 := msgLayer.(*MibUploadNextResponse)
488 assert.True(t, ok2)
489 assert.NotNil(t, response)
490 assert.Equal(t, LayerTypeMibUploadNextResponse, response.LayerType())
491 assert.Equal(t, LayerTypeMibUploadNextResponse, response.CanDecode())
492 assert.Equal(t, me.OltGClassID, response.ReportedME.GetClassID())
493 assert.Equal(t, uint16(0), response.ReportedME.GetEntityID())
494
495 // The attribute mask decoded at this layer only contains the attributes we
496 // could successfully decode
497 assert.Equal(t, uint16(0x1000), response.ReportedME.GetAttributeMask())
498
499 attributes := me.AttributeValueMap{
500 "TimeOfDayInformation": goodAttributeData, // NOTE: This is binary data for the comparison below
501 }
502 for name, value := range attributes {
503 pktValue, err := response.ReportedME.GetAttribute(name)
504 assert.Nil(t, err)
505 assert.Equal(t, pktValue, value)
506 }
507 // Now the second ME in the response
508 assert.NotNil(t, response.AdditionalMEs)
509 assert.Equal(t, 1, len(response.AdditionalMEs))
510
511 ////////////////////////////////////////////////////////////////////////////
512 // Here is the new functionality. In order to store both a well decoded
513 // MIB UPLOAD NEXT response layer, along with a relaxed decode error, the
514 // layer addition has to be done in a specific way and an error returned.
515 //
516 // Note that the previous line (below) worked in the code above
517 //
518 // response, ok2 := msgLayer.(*MibUploadNextResponse)
519 //
520 // If you did not care about what the relaxed decode found out, just proceed
521 // on as normal. However, since you enabled relaxed decoding of the unknown
522 // attributes, here is where you can pull extra information from.
523 //
524 // The first way is to just try and see if that error layer was decoded
525 //
526 // if unknownAttrLayer = packet.Layer(LayerTypeUnknownAttributes); unknownAttrLayer != nil {
527 // log.warning(HEY! Got some unknown attributes to this ME: '%v', unknownAttrLayer)
528 //
529 // unknownAttributes, ok2 := msgLayer.(*UnknownAttributes); ok {
530 // //
531 // // Since some extended messages can actually return multiple managed entities,
532 // // all ME's with unknown attributes need to be uniquely identified
533 // //
534 // for _, unknown := range unknownAttibutes.Attributes {
535 // whichME := unknown.EntityClass // ClassID
536 // whichInst := unknown.EntityInstance // uint16
537 // unknownMask := unknown.AttributeMask // uint16
538 // unknownBlob := unknown.Attributes // []byte
539 //
540 // // Unless this is the extended message set and only a single attribute
541 // // mask bit is set, you really do not know what possible kind of data
542 // // type the attribute is...
543 // }
544 // }
545 // }
546 /////////////////////////////////////
547 assert.NotEqual(t, gopacket.LayerTypePayload, response.NextLayerType())
548 assert.Equal(t, LayerTypeUnknownAttributes, response.NextLayerType())
549
550 unknownAttrLayer := packet.Layer(LayerTypeUnknownAttributes)
551 assert.NotNil(t, unknownAttrLayer)
552
553 unknown, ok2 := unknownAttrLayer.(*UnknownAttributes)
554 assert.True(t, ok2)
555 assert.NotNil(t, unknown)
556 assert.Equal(t, LayerTypeUnknownAttributes, unknown.LayerType())
557 assert.Equal(t, LayerTypeUnknownAttributes, unknown.CanDecode())
558 assert.Equal(t, gopacket.LayerTypeZero, unknown.NextLayerType())
559
560 // Only one Managed entity was in this response and had a bad attribute
561 assert.Equal(t, 2, len(unknown.Attributes))
562 assert.Equal(t, me.OltGClassID, unknown.Attributes[0].EntityClass)
563 assert.Equal(t, uint16(0), unknown.Attributes[0].EntityInstance)
564 assert.Equal(t, uint16(0x0c00), unknown.Attributes[0].AttributeMask)
565 assert.Equal(t, extraTrailerData1, unknown.Attributes[0].AttributeData)
566
567 assert.Equal(t, me.OltGClassID, unknown.Attributes[1].EntityClass)
568 assert.Equal(t, uint16(1), unknown.Attributes[1].EntityInstance)
569 assert.Equal(t, uint16(0x0c00), unknown.Attributes[1].AttributeMask)
570 assert.Equal(t, extraTrailerData2, unknown.Attributes[1].AttributeData)
571
572 errStr := unknown.Error()
573 assert.NotNil(t, errStr)
574 assert.Greater(t, len(errStr.Error()), 0)
575}