blob: a8549a157a0004ea89368f2d37169fb685d6f8d3 [file] [log] [blame]
Chip Boling610117d2021-09-09 11:24:34 -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
19
20import (
21 "encoding/binary"
22 "errors"
23 "fmt"
24 "github.com/google/gopacket"
25 me "github.com/opencord/omci-lib-go/generated"
26)
27
28type MibUploadRequest struct {
29 MeBasePacket
30}
31
32func (omci *MibUploadRequest) String() string {
33 return fmt.Sprintf("%v", omci.MeBasePacket.String())
34}
35
36// LayerType returns LayerTypeMibUploadRequest
37func (omci *MibUploadRequest) LayerType() gopacket.LayerType {
38 return LayerTypeMibUploadRequest
39}
40
41// CanDecode returns the set of layer types that this DecodingLayer can decode
42func (omci *MibUploadRequest) CanDecode() gopacket.LayerClass {
43 return LayerTypeMibUploadRequest
44}
45
46// NextLayerType returns the layer type contained by this DecodingLayer.
47func (omci *MibUploadRequest) NextLayerType() gopacket.LayerType {
48 return gopacket.LayerTypePayload
49}
50
51// DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
52func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
53 // Common ClassID/EntityID decode in msgBase
54 var hdrSize int
55 if omci.Extended {
56 hdrSize = 6
57 } else {
58 hdrSize = 4
59 }
60 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
61 if err != nil {
62 return err
63 }
64 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
65 me.ParamData{EntityID: omci.EntityInstance})
66 if omciErr.StatusCode() != me.Success {
67 return omciErr.GetError()
68 }
69 // ME needs to support MIB Upload
70 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
71 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
72 }
73 // Entity Class are always ONU DATA (2) and Entity Instance of 0
74 if omci.EntityClass != me.OnuDataClassID {
75 msg := fmt.Sprintf("invalid Entity Class for MIB Upload request: %v",
76 omci.EntityClass)
77 return me.NewProcessingError(msg)
78 }
79 if omci.EntityInstance != 0 {
80 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload request: %v",
81 omci.EntityInstance)
82 return me.NewUnknownInstanceError(msg)
83 }
84 return nil
85}
86
87func decodeMibUploadRequest(data []byte, p gopacket.PacketBuilder) error {
88 omci := &MibUploadRequest{}
89 omci.MsgLayerType = LayerTypeMibUploadRequest
90 return decodingLayerDecoder(omci, data, p)
91}
92
93func decodeMibUploadRequestExtended(data []byte, p gopacket.PacketBuilder) error {
94 omci := &MibUploadRequest{}
95 omci.MsgLayerType = LayerTypeMibUploadRequest
96 omci.Extended = true
97 return decodingLayerDecoder(omci, data, p)
98}
99
100// SerializeTo provides serialization of an MIB Upload Request message
101func (omci *MibUploadRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
102 // Basic (common) OMCI Header is 8 octets, 10
103 err := omci.MeBasePacket.SerializeTo(b)
104 if err != nil {
105 return err
106 }
107 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
108 me.ParamData{EntityID: omci.EntityInstance})
109 if omciErr.StatusCode() != me.Success {
110 return omciErr.GetError()
111 }
112 // ME needs to support Get
113 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
114 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
115 }
116 // Add length if extended ident
117 if omci.Extended {
118 bytes, err := b.AppendBytes(2)
119 if err != nil {
120 return err
121 }
122 binary.BigEndian.PutUint16(bytes, 0)
123 }
124 return nil
125}
126
127type MibUploadResponse struct {
128 MeBasePacket
129 NumberOfCommands uint16
130}
131
132func (omci *MibUploadResponse) String() string {
133 return fmt.Sprintf("%v, NumberOfCommands: %#v",
134 omci.MeBasePacket.String(), omci.NumberOfCommands)
135}
136
137// LayerType returns LayerTypeMibUploadResponse
138func (omci *MibUploadResponse) LayerType() gopacket.LayerType {
139 return LayerTypeMibUploadResponse
140}
141
142// CanDecode returns the set of layer types that this DecodingLayer can decode
143func (omci *MibUploadResponse) CanDecode() gopacket.LayerClass {
144 return LayerTypeMibUploadResponse
145}
146
147// NextLayerType returns the layer type contained by this DecodingLayer.
148func (omci *MibUploadResponse) NextLayerType() gopacket.LayerType {
149 return gopacket.LayerTypePayload
150}
151
152// DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
153func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
154 // Common ClassID/EntityID decode in msgBase
155 var hdrSize int
156 if omci.Extended {
157 hdrSize = 6 + 2
158 } else {
159 hdrSize = 4 + 2
160 }
161 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
162 if err != nil {
163 return err
164 }
165 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
166 me.ParamData{EntityID: omci.EntityInstance})
167 if omciErr.StatusCode() != me.Success {
168 return omciErr.GetError()
169 }
170 // ME needs to support MIB Upload
171 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
172 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
173 }
174 // Entity Class are always ONU DATA (2) and Entity Instance of 0
175 if omci.EntityClass != me.OnuDataClassID {
176 msg := fmt.Sprintf("invalid Entity Class for MIB Upload response: %v",
177 omci.EntityClass)
178 return me.NewProcessingError(msg)
179 }
180 if omci.EntityInstance != 0 {
181 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload response: %v",
182 omci.EntityInstance)
183 return me.NewUnknownInstanceError(msg)
184 }
185 offset := hdrSize - 2
186 omci.NumberOfCommands = binary.BigEndian.Uint16(data[offset:])
187 return nil
188}
189
190func decodeMibUploadResponse(data []byte, p gopacket.PacketBuilder) error {
191 omci := &MibUploadResponse{}
192 omci.MsgLayerType = LayerTypeMibUploadResponse
193 return decodingLayerDecoder(omci, data, p)
194}
195
196func decodeMibUploadResponseExtended(data []byte, p gopacket.PacketBuilder) error {
197 omci := &MibUploadResponse{}
198 omci.MsgLayerType = LayerTypeMibUploadResponse
199 omci.Extended = true
200 return decodingLayerDecoder(omci, data, p)
201}
202
203// SerializeTo provides serialization of an MIB Upload Response message
204func (omci *MibUploadResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
205 // Basic (common) OMCI Header
206 err := omci.MeBasePacket.SerializeTo(b)
207 if err != nil {
208 return err
209 }
210 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
211 me.ParamData{EntityID: omci.EntityInstance})
212 if omciErr.StatusCode() != me.Success {
213 return omciErr.GetError()
214 }
215 // ME needs to support MIB Upload
216 if !me.SupportsMsgType(entity, me.MibUpload) {
217 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
218 }
219 var offset int
220 if omci.Extended {
221 offset = 2
222 }
223 bytes, err := b.AppendBytes(offset + 2)
224 if err != nil {
225 return err
226 }
227 // Add length if extended ident
228 if omci.Extended {
229 binary.BigEndian.PutUint16(bytes, 2)
230 }
231 binary.BigEndian.PutUint16(bytes[offset:], omci.NumberOfCommands)
232 return nil
233}
234
235type MibUploadNextRequest struct {
236 MeBasePacket
237 CommandSequenceNumber uint16
238}
239
240func (omci *MibUploadNextRequest) String() string {
241 return fmt.Sprintf("%v, SequenceNumberCountOrSize: %v",
242 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
243}
244
245// LayerType returns LayerTypeMibUploadNextRequest
246func (omci *MibUploadNextRequest) LayerType() gopacket.LayerType {
247 return LayerTypeMibUploadNextRequest
248}
249
250// CanDecode returns the set of layer types that this DecodingLayer can decode
251func (omci *MibUploadNextRequest) CanDecode() gopacket.LayerClass {
252 return LayerTypeMibUploadNextRequest
253}
254
255// NextLayerType returns the layer type contained by this DecodingLayer.
256func (omci *MibUploadNextRequest) NextLayerType() gopacket.LayerType {
257 return gopacket.LayerTypePayload
258}
259
260// DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
261func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
262 // Common ClassID/EntityID decode in msgBase
263 var hdrSize int
264 if omci.Extended {
265 hdrSize = 6 + 2
266 } else {
267 hdrSize = 4 + 2
268 }
269 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
270 if err != nil {
271 return err
272 }
273 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
274 me.ParamData{EntityID: omci.EntityInstance})
275 if omciErr.StatusCode() != me.Success {
276 return omciErr.GetError()
277 }
278 // ME needs to support Get All Alarms
279 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
280 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
281 }
282 // Entity Class are always ONU DATA (2) and Entity Instance of 0
283 if omci.EntityClass != me.OnuDataClassID {
284 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next request: %v",
285 omci.EntityClass)
286 return me.NewProcessingError(msg)
287 }
288 if omci.EntityInstance != 0 {
289 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next request: %v",
290 omci.EntityInstance)
291 return me.NewUnknownInstanceError(msg)
292 }
293 var offset int
294 if omci.Extended {
295 offset = 2
296 }
297 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4+offset:])
298 return nil
299}
300
301func decodeMibUploadNextRequest(data []byte, p gopacket.PacketBuilder) error {
302 omci := &MibUploadNextRequest{}
303 omci.MsgLayerType = LayerTypeMibUploadNextRequest
304 return decodingLayerDecoder(omci, data, p)
305}
306
307func decodeMibUploadNextRequestExtended(data []byte, p gopacket.PacketBuilder) error {
308 omci := &MibUploadNextRequest{}
309 omci.MsgLayerType = LayerTypeMibUploadNextRequest
310 omci.Extended = true
311 return decodingLayerDecoder(omci, data, p)
312}
313
314// SerializeTo provides serialization of an MIB Upload Next Request message
315func (omci *MibUploadNextRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
316 // Basic (common) OMCI Header is 8 octets, 10
317 err := omci.MeBasePacket.SerializeTo(b)
318 if err != nil {
319 return err
320 }
321 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
322 me.ParamData{EntityID: omci.EntityInstance})
323 if omciErr.StatusCode() != me.Success {
324 return omciErr.GetError()
325 }
326 // ME needs to support MIB upload
327 if !me.SupportsMsgType(entity, me.MibUploadNext) {
328 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
329 }
330 var offset int
331 if omci.Extended {
332 offset = 2
333 }
334 bytes, err := b.AppendBytes(2 + offset)
335 if err != nil {
336 return err
337 }
338 if omci.Extended {
339 binary.BigEndian.PutUint16(bytes, 2)
340 }
341 binary.BigEndian.PutUint16(bytes[offset:], omci.CommandSequenceNumber)
342 return nil
343}
344
345type IMibUploadNextResponse interface {
346 GetMeBasePacket() *MeBasePacket
347 GetMeCount() int
348 GetManagedEntity(int) *me.ManagedEntity
349 AddManagedEntity(*me.ManagedEntity) error
350}
351
352type MibUploadNextResponse struct {
353 MeBasePacket
354 ReportedME me.ManagedEntity
355 AdditionalMEs []me.ManagedEntity // Valid only for extended message set version
Chip Boling934e1052021-09-27 15:12:06 -0500356
357 RelaxedErrors []me.IRelaxedDecodeError
Chip Boling610117d2021-09-09 11:24:34 -0500358}
359
360type MibUploadNextManageEntity struct {
361 AttrSize uint16 // Size of ME instance attribute values included
362 ReportedME me.ManagedEntity
363}
364
365func (omci *MibUploadNextResponse) String() string {
366 return fmt.Sprintf("%v, ReportedME: [%v]",
367 omci.MeBasePacket.String(), omci.ReportedME.String())
368}
369
370// LayerType returns LayerTypeMibUploadNextResponse
371func (omci *MibUploadNextResponse) LayerType() gopacket.LayerType {
372 return LayerTypeMibUploadNextResponse
373}
374
375// CanDecode returns the set of layer types that this DecodingLayer can decode
376func (omci *MibUploadNextResponse) CanDecode() gopacket.LayerClass {
377 return LayerTypeMibUploadNextResponse
378}
379
380// NextLayerType returns the layer type contained by this DecodingLayer.
381func (omci *MibUploadNextResponse) NextLayerType() gopacket.LayerType {
Chip Boling934e1052021-09-27 15:12:06 -0500382
383 if omci.RelaxedErrors != nil && len(omci.RelaxedErrors) > 0 {
384 return LayerTypeUnknownAttributes
385 }
Chip Boling610117d2021-09-09 11:24:34 -0500386 return gopacket.LayerTypePayload
387}
388
Chip Boling934e1052021-09-27 15:12:06 -0500389// addRelaxedError appends relaxed decode errors to this message
390func (omci *MibUploadNextResponse) addRelaxedError(err me.IRelaxedDecodeError) {
391 if omci.RelaxedErrors == nil {
392 omci.RelaxedErrors = make([]me.IRelaxedDecodeError, 0)
393 }
394 omci.RelaxedErrors = append(omci.RelaxedErrors, err)
395}
396
Chip Boling610117d2021-09-09 11:24:34 -0500397// DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
398func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
399 // Common ClassID/EntityID decode in msgBase
400 var hdrSize int
401 if omci.Extended {
402 hdrSize = 6
403 } else {
404 hdrSize = 4
405 }
406 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
407 if err != nil {
408 return err
409 }
410 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
411 me.ParamData{EntityID: omci.EntityInstance})
412 if omciErr.StatusCode() != me.Success {
413 return omciErr.GetError()
414 }
415 // ME needs to support MibUploadNext
416 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
417 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
418 }
419 // Entity Class are always ONU DATA (2) and Entity Instance of 0
420 if omci.EntityClass != me.OnuDataClassID {
421 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next response: %v",
422 omci.EntityClass)
423 return me.NewProcessingError(msg)
424 }
425 if omci.EntityInstance != 0 {
426 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next response: %v",
427 omci.EntityInstance)
428 return me.NewUnknownInstanceError(msg)
429 }
430 // Decode reported ME. If an out-of-range sequence number was sent, this will
431 // contain an ME with class ID and entity ID of zero and you should get an
432 // error of "managed entity definition not found" returned.
433 var offset int
434 var attrLen int
Chip Boling934e1052021-09-27 15:12:06 -0500435 meLength := len(data)
Chip Boling610117d2021-09-09 11:24:34 -0500436 if omci.Extended {
437 offset = 2 + 2 // Message Contents length (2) + first ME attribute values len (2)
438 attrLen = int(binary.BigEndian.Uint16(data[6:]))
Chip Boling934e1052021-09-27 15:12:06 -0500439 meLength = 4 + offset + 6 + attrLen
Chip Boling610117d2021-09-09 11:24:34 -0500440
441 if len(data[4+offset:]) < 6+attrLen {
442 p.SetTruncated()
443 return errors.New("frame too small: MIB Upload Response Managed Entity attribute truncated")
444 }
445 }
Chip Boling934e1052021-09-27 15:12:06 -0500446 err = omci.ReportedME.DecodeFromBytes(data[4+offset:meLength], p, byte(MibUploadNextResponseType))
447 if err != nil {
448 attrError, ok := err.(*me.UnknownAttributeDecodeError)
449
450 // Error if relaxed decode not supported or other error signalled
451 if !ok || !me.GetRelaxedDecode(me.MibUploadNext, false) {
452 return err
453 }
454 // Save off which Managed Entity had the issue
455 attrError.EntityClass = omci.ReportedME.GetClassID()
456 attrError.EntityInstance = omci.ReportedME.GetEntityID()
457 if attrError.Contents != nil && !omci.Extended {
458 attrLen += len(attrError.Contents)
459 }
460 omci.addRelaxedError(attrError)
461 err = nil
Chip Boling610117d2021-09-09 11:24:34 -0500462 }
Chip Boling934e1052021-09-27 15:12:06 -0500463 if err == nil && omci.Extended {
464 // Handle extended message set decode here for additional managed entities
465 data = data[meLength:]
466 if len(data) > 0 {
467 omci.AdditionalMEs = make([]me.ManagedEntity, 0)
468 }
469 for len(data) > 0 {
470 if len(data) < 8 {
Chip Boling610117d2021-09-09 11:24:34 -0500471 p.SetTruncated()
472 // TODO: Review all "frame to small" and add an extra hint for developers
473 return errors.New("frame too small: MIB Upload Response Managed Entity header truncated")
474 }
475 additional := me.ManagedEntity{}
Chip Boling934e1052021-09-27 15:12:06 -0500476 attrLen = int(binary.BigEndian.Uint16(data))
477 meLength = 8 + attrLen
Chip Boling610117d2021-09-09 11:24:34 -0500478
Chip Boling934e1052021-09-27 15:12:06 -0500479 if len(data) < meLength {
Chip Boling610117d2021-09-09 11:24:34 -0500480 p.SetTruncated()
481 return errors.New("frame too small: MIB Upload Response Managed Entity attribute truncated")
482 }
Chip Boling934e1052021-09-27 15:12:06 -0500483 err = additional.DecodeFromBytes(data[2:meLength], p, byte(MibUploadNextResponseType))
Chip Boling610117d2021-09-09 11:24:34 -0500484 if err != nil {
Chip Boling934e1052021-09-27 15:12:06 -0500485 attrError, ok := err.(*me.UnknownAttributeDecodeError)
486
487 // Error if relaxed decode not supported
488 if !ok || !me.GetRelaxedDecode(me.MibUploadNext, false) {
489 return err
490 }
491 // Save off which Managed Entity had the issue
492 attrError.EntityClass = additional.GetClassID()
493 attrError.EntityInstance = additional.GetEntityID()
494 omci.addRelaxedError(attrError)
495 err = nil
Chip Boling610117d2021-09-09 11:24:34 -0500496 }
497 omci.AdditionalMEs = append(omci.AdditionalMEs, additional)
Chip Boling934e1052021-09-27 15:12:06 -0500498 data = data[meLength:]
Chip Boling610117d2021-09-09 11:24:34 -0500499 }
500 }
Chip Boling934e1052021-09-27 15:12:06 -0500501 if err == nil && omci.RelaxedErrors != nil && len(omci.RelaxedErrors) > 0 {
502 // Create our error layer now
503 err = newUnknownAttributesLayer(omci, omci.RelaxedErrors, p)
504 }
505 return err
Chip Boling610117d2021-09-09 11:24:34 -0500506}
507
508func decodeMibUploadNextResponse(data []byte, p gopacket.PacketBuilder) error {
509 omci := &MibUploadNextResponse{}
510 omci.MsgLayerType = LayerTypeMibUploadNextResponse
511 return decodingLayerDecoder(omci, data, p)
512}
513
514func decodeMibUploadNextResponseExtended(data []byte, p gopacket.PacketBuilder) error {
515 omci := &MibUploadNextResponse{}
516 omci.MsgLayerType = LayerTypeMibUploadNextResponse
517 omci.Extended = true
518 return decodingLayerDecoder(omci, data, p)
519}
520
521// SerializeTo provides serialization of an MIB Upload Next Response message
522func (omci *MibUploadNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
523 // Basic (common) OMCI Header
524 err := omci.MeBasePacket.SerializeTo(b)
525 if err != nil {
526 return err
527 }
528 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
529 me.ParamData{EntityID: omci.EntityInstance})
530 if omciErr.StatusCode() != me.Success {
531 return omciErr.GetError()
532 }
533 // ME needs to support MIB Upload
534 if !me.SupportsMsgType(entity, me.MibUploadNext) {
535 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
536 }
537 bytesAvailable := MaxBaselineLength - 8 - 8
538
539 if omci.Extended {
540 bytesAvailable = MaxExtendedLength - 10 - 4
541 }
542 attributeBuffer := gopacket.NewSerializeBuffer()
543 attrErr := omci.ReportedME.SerializeTo(attributeBuffer, byte(MibUploadNextResponseType), bytesAvailable, opts)
544 if attrErr != nil {
545 return attrErr
546 }
547 var offset int
548 if omci.Extended {
549 offset = 2 + 2 // Message Contents length (2) + first ME attribute values len (2)
550 }
551 meLength := len(attributeBuffer.Bytes())
552 buf, attrErr := b.AppendBytes(meLength + offset)
553 if attrErr != nil {
554 return attrErr
555 }
556 if omci.Extended {
557 binary.BigEndian.PutUint16(buf, uint16(meLength+2))
558 binary.BigEndian.PutUint16(buf[2:], uint16(meLength-6))
559 }
560 copy(buf[offset:], attributeBuffer.Bytes())
561
562 if omci.Extended && omci.AdditionalMEs != nil {
563 // Handle additional Managed Entities here for the Extended Message set
564 bytesAvailable -= 4 + meLength
565 length := meLength + 2
566
567 for index, entry := range omci.AdditionalMEs {
568 if bytesAvailable <= 8 {
569 msg := fmt.Sprintf("not enough space to fit all requested Managed Entities, entry: %v", index)
570 attrErr = me.NewMessageTruncatedError(msg)
571 if attrErr != nil {
572 return attrErr
573 }
574 }
575 attributeBuffer = gopacket.NewSerializeBuffer()
576 attrErr = entry.SerializeTo(attributeBuffer, byte(MibUploadNextResponseType), bytesAvailable, opts)
577 if attrErr != nil {
578 return attrErr
579 }
580 meLength = len(attributeBuffer.Bytes())
581 buf, attrErr = b.AppendBytes(2 + meLength)
582 if attrErr != nil {
583 return attrErr
584 }
585 binary.BigEndian.PutUint16(buf, uint16(meLength-6))
586 copy(buf[2:], attributeBuffer.Bytes())
587 length += 2 + meLength
588 bytesAvailable -= 2 + meLength
589 }
590 msgBuffer := b.Bytes()
591 binary.BigEndian.PutUint16(msgBuffer[4:], uint16(length))
592 }
593 return nil
594}