blob: b835817f6ad3b3d1ca601afc8ab681d85f78e638 [file] [log] [blame]
/*
* Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
* Copyright 2020-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package omci
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
me "github.com/opencord/omci-lib-go/v2/generated"
)
type UnknownAttributeInfo struct {
EntityClass me.ClassID
EntityInstance uint16
AttributeMask uint16
AttributeData []byte
}
type UnknownAttributes struct {
// Each Attributes entry relates one or more unknown attributes to a specific managed
// entity. For message types such as MIB Upload Next responses, there may be multiple
// Managed Entities in a single response if the Extended Message set is being used.
Attributes []UnknownAttributeInfo
gopacket.Layer
layers.BaseLayer
MsgLayerType gopacket.LayerType
}
// SerializeTo provides serialization of an Get Next Message Type Response
func (msg *UnknownAttributes) String() string {
return fmt.Sprintf("Unknown Attributes, %v Managed Entities", len(msg.Attributes))
}
// LayerType returns LayerTypeGetNextResponse
func (msg *UnknownAttributes) LayerType() gopacket.LayerType {
return LayerTypeUnknownAttributes
}
// CanDecode returns the set of layer types that this DecodingLayer can decode
func (msg *UnknownAttributes) CanDecode() gopacket.LayerClass {
return LayerTypeUnknownAttributes
}
// LayerContents returns the bytes of the packet layer.
func (msg *UnknownAttributes) LayerContents() []byte {
return msg.Contents
}
// LayerPayload returns the bytes contained within the packet layer
func (msg *UnknownAttributes) LayerPayload() []byte {
return msg.Payload
}
// NextLayerType returns the layer type contained by this DecodingLayer.
func (msg *UnknownAttributes) NextLayerType() gopacket.LayerType {
return gopacket.LayerTypeZero
}
// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
func (msg *UnknownAttributes) DecodeFromBytes(_ []byte, _ gopacket.PacketBuilder) error {
// This is not a real layer. It is used to pass on relaxed decode error information
// as an ErrorLayer
return fmt.Errorf("This function is never called. This is an error layer that gets assigned")
}
func decodeUnknownAttributes(_ []byte, _ gopacket.PacketBuilder) error {
return fmt.Errorf("This function is never called. This is an error layer that gets assigned")
}
func (msg *UnknownAttributes) Error() error {
return fmt.Errorf("%v managed entities with Unknown Attributes detected during decode",
len(msg.Attributes))
}
func newUnknownAttributesLayer(prevLayer gopacket.Layer, errInfo []me.IRelaxedDecodeError, p gopacket.PacketBuilder) error {
// Add the previous layer
p.AddLayer(prevLayer)
// Append unknown attributes layer and also set ErrorLayer
errLayer := &UnknownAttributes{
Attributes: make([]UnknownAttributeInfo, 0),
MsgLayerType: LayerTypeUnknownAttributes,
}
for _, item := range errInfo {
unknown, ok := item.(*me.UnknownAttributeDecodeError)
if !ok {
return fmt.Errorf("only UnknownAttributeDecodeError information can be encoded. Found %T",
unknown)
}
data := UnknownAttributeInfo{
EntityClass: unknown.EntityClass,
EntityInstance: unknown.EntityInstance,
AttributeMask: unknown.AttributeMask,
}
if unknown.Contents != nil {
data.AttributeData = make([]byte, len(unknown.Contents))
copy(data.AttributeData, unknown.Contents)
}
errLayer.Attributes = append(errLayer.Attributes, data)
}
p.AddLayer(errLayer)
p.SetErrorLayer(errLayer)
// Return a valid error so that packet decoding stops
return errLayer.Error()
}