blob: 4b2061afc3f290e1f9be9374b648eedd31f25af4 [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.
*/
/*
* NOTE: This file was generated, manual edits will be overwritten!
*
* Generated by 'goCodeGenerator.py':
* https://github.com/cboling/OMCI-parser/README.md
*/
package generated
import (
"errors"
"fmt"
"github.com/deckarep/golang-set"
"github.com/google/gopacket"
"math/bits"
)
// ManagedEntityDefinition defines a Manage Entity
type ManagedEntityDefinition struct {
Name string
ClassID ClassID
MessageTypes mapset.Set // Mandatory
AllowedAttributeMask uint16
AttributeDefinitions AttributeDefinitionMap
Access ClassAccess
Support ClassSupport
Alarms AlarmMap // AlarmBit -> AlarmName
}
func (bme *ManagedEntityDefinition) String() string {
return fmt.Sprintf("Definition: %s: CID: %v, Attributes: %v",
bme.Name, bme.ClassID, bme.AttributeDefinitions)
}
// GetName retrieves the name of a managed entity from a ME Definition
func (bme ManagedEntityDefinition) GetName() string {
return bme.Name
}
// GetClassID retrieves the 16-bit class ID of a managed entity from a ME Definition
func (bme ManagedEntityDefinition) GetClassID() ClassID {
return bme.ClassID
}
// SetClassID assigns the 16-bit class ID of a managed entity from a ME Definition
func (bme *ManagedEntityDefinition) SetClassID(classID ClassID) {
bme.ClassID = classID
}
// GetMessageTypes retrieves the OMCI Message Types supporte3d by a managed entity from a ME Definition
func (bme ManagedEntityDefinition) GetMessageTypes() mapset.Set {
return bme.MessageTypes
}
// GetAllowedAttributeMask retrieves the allowed/valid 16-bit attribute mask of a managed entity
// from a ME Definition
func (bme ManagedEntityDefinition) GetAllowedAttributeMask() uint16 {
return bme.AllowedAttributeMask
}
// GetAttributeDefinitions retrieves the attribute definitions of a managed entity from a ME Definition
func (bme ManagedEntityDefinition) GetAttributeDefinitions() AttributeDefinitionMap {
return bme.AttributeDefinitions
}
// GetClassSupport returns ONUs support of this class
func (bme ManagedEntityDefinition) GetClassSupport() ClassSupport {
return bme.Support
}
// GetAlarmMap returns the Alarm bit number to name map
func (bme ManagedEntityDefinition) GetAlarmMap() AlarmMap {
return bme.Alarms
}
func (bme ManagedEntityDefinition) DecodeAttributes(mask uint16, data []byte, p gopacket.PacketBuilder, msgType byte) (AttributeValueMap, error) {
badMask := (mask | bme.GetAllowedAttributeMask()) ^ bme.GetAllowedAttributeMask()
var maskErr error
if badMask != 0 {
maskErr = fmt.Errorf("unsupported attribute mask %#x, valid: %#x for ME %v (Class ID: %d)",
mask, bme.GetAllowedAttributeMask(), bme.GetName(), bme.ClassID)
mask &= bme.GetAllowedAttributeMask()
}
// Process known attributes
keyList := GetAttributeDefinitionMapKeys(bme.AttributeDefinitions)
attrMap := make(AttributeValueMap, bits.OnesCount16(mask))
for _, index := range keyList {
if index == 0 {
continue // Skip Entity ID
}
attrDef := bme.AttributeDefinitions[index]
name := attrDef.GetName()
if mask&attrDef.Mask != 0 {
value, err := attrDef.Decode(data, p, msgType)
if err != nil {
return nil, err
}
if attrDef.IsTableAttribute() {
switch msgType {
default:
return nil, fmt.Errorf("unsupported Message Type '%v/0x%02x' for table decode",
MsgType(msgType&MsgTypeMask), msgType)
case byte(Get) | AK: // Get Response
attrMap[name] = value
data = data[4:]
case byte(GetNext) | AK: // Get Next Response
// Value is a partial octet buffer we need to collect and at
// the end (last segment) pull it up into more appropriate table
// rows
valueBuffer, ok := value.([]byte)
if !ok {
panic("unexpected type already returned as get-next-response attribute data")
}
if existing, found := attrMap[name]; found {
prev, ok := existing.([]byte)
if !ok {
panic("unexpected type already in attribute value map")
}
attrMap[name] = append(prev, valueBuffer...)
} else {
attrMap[name] = valueBuffer
}
if size := attrDef.GetSize(); size != 0 && size > len(valueBuffer) {
panic("unexpected size difference")
}
data = data[len(valueBuffer):]
case byte(Set) | AR: // Set Request
// TODO: No support at this time
case byte(SetTable) | AR: // Set Table Request
attrMap[name] = value
data = data[len(data):]
}
} else {
attrMap[name] = value
data = data[attrDef.GetSize():]
}
}
}
// If badMask is non-zero. Handle it by re-encoding the error as a custom relaxed
// decode error that the caller of this decode can process if they wish to relax
// the decoding
if badMask != 0 {
maskErr = NewUnknownAttributeDecodeError(maskErr.Error(), badMask, data)
}
return attrMap, maskErr
}
func (bme ManagedEntityDefinition) SerializeAttributes(attr AttributeValueMap, mask uint16,
b gopacket.SerializeBuffer, msgType byte, bytesAvailable int, packData bool) (error, uint16) {
if (mask | bme.GetAllowedAttributeMask()) != bme.GetAllowedAttributeMask() {
// TODO: Provide custom error code so a response 'result' can properly be coded
return errors.New("unsupported attribute mask"), 0
}
// TODO: Need to limit number of bytes appended to not exceed packet size
// Is there space/metadata info in 'b' parameter to allow this?
keyList := GetAttributeDefinitionMapKeys(bme.AttributeDefinitions)
var failedMask uint16
for _, index := range keyList {
if index == 0 {
continue // Skip Entity ID
}
attrDef := bme.AttributeDefinitions[index]
if mask&attrDef.Mask != 0 {
value, ok := attr[attrDef.GetName()]
if !ok {
msg := fmt.Sprintf("attribute not found: '%v'", attrDef.GetName())
return errors.New(msg), failedMask
}
size, err := attrDef.SerializeTo(value, b, msgType, bytesAvailable)
if err != nil {
failedMask |= attrDef.Mask
if packData {
continue
}
return err, failedMask
}
bytesAvailable -= size
}
}
return nil, failedMask
}