| /* |
| * 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 |
| } |