/*
 * 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 "github.com/deckarep/golang-set"

// VirtualEthernetInterfacePointClassID is the 16-bit ID for the OMCI
// Managed entity Virtual Ethernet interface point
const VirtualEthernetInterfacePointClassID = ClassID(329) // 0x0149

var virtualethernetinterfacepointBME *ManagedEntityDefinition

// VirtualEthernetInterfacePoint (Class ID: #329 / 0x0149)
//	This ME represents the data plane hand-off point in an ONU to a separate (non-OMCI) management
//	domain. The VEIP is managed by the OMCI, and is potentially known to the non-OMCI management
//	domain. One or more Ethernet traffic flows are present at this boundary.
//
//	Instances of this ME are automatically created and deleted by the ONU. This is necessary because
//	the required downstream priority queues are subject to physical implementation constraints. The
//	OLT may use one or more of the VEIPs created by the ONU.
//
//	It is expected that the ONU will create one VEIP for each non-OMCI management domain. At the
//	vendor's discretion, a VEIP may be created for each traffic class.
//
//	Relationships
//		An instance of this ME is associated with an instance of a virtual Ethernet interface between
//		OMCI and non-OMCI management domains.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. When used independently of a
//			cardholder and circuit pack, the ONU should assign IDs in the sequence 1, 2, .... When used in
//			conjunction with a cardholder and circuit pack, this 2 byte number indicates the physical
//			position of the VEIP. The first byte is the slot ID (defined in clause 9.1.5). The second byte
//			is the port ID, with the range 1..255. The values 0 and 0xFFFF are reserved. (R) (mandatory) (2
//			bytes)
//
//		Administrative State
//			This attribute locks (1) and unlocks (0) the functions performed by this ME. Administrative
//			state is further described in clause A.1.6. (R,-W) (mandatory) (1-byte)
//
//		Operational State
//			This attribute indicates whether the ME is capable of performing its function. Valid values are
//			enabled (0) and disabled (1). (R) (optional) (1-byte)
//
//		Interdomain Name
//			This attribute is a character string that provides an optional way to identify the VEIP to a
//			non-OMCI management domain. The interface may also be identified by its ME ID,  [b-IANA]
//			assigned port and possibly other ways. If the vendor offers no information in this attribute, it
//			should be set to a sequence of null bytes. (R,-W) (optional) (25-bytes)
//
//		Tcp_Udp Pointer
//			TCP/UDP pointer: This attribute points to an instance of the TCP/UDP config data ME, which
//			provides for OMCI management of the non-OMCI management domain's IP connectivity. If no OMCI
//			management of the non-OMCI domain's IP connectivity is required, this attribute may be omitted
//			or set to its default, a null pointer. (R,-W) (optional) (2-bytes)
//
//		Iana Assigned Port
//			This attribute contains the TCP or UDP port value as assigned by  [b-IANA] for the management
//			protocol associated with this virtual Ethernet interface. This attribute is to be regarded as a
//			hint, not as a requirement that management communications use this port; the actual port and
//			protocol are specified in the associated TCP/UDP config data ME. If no port has been assigned or
//			if the management protocol is free to be chosen at run-time, this attribute should be set to
//			0xFFFF. (R) (mandatory) (2-bytes)
//
type VirtualEthernetInterfacePoint struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const VirtualEthernetInterfacePoint_AdministrativeState = "AdministrativeState"
const VirtualEthernetInterfacePoint_OperationalState = "OperationalState"
const VirtualEthernetInterfacePoint_InterdomainName = "InterdomainName"
const VirtualEthernetInterfacePoint_TcpUdpPointer = "TcpUdpPointer"
const VirtualEthernetInterfacePoint_IanaAssignedPort = "IanaAssignedPort"

func init() {
	virtualethernetinterfacepointBME = &ManagedEntityDefinition{
		Name:    "VirtualEthernetInterfacePoint",
		ClassID: VirtualEthernetInterfacePointClassID,
		MessageTypes: mapset.NewSetWith(
			Get,
			Set,
		),
		AllowedAttributeMask: 0xf800,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: ByteField(VirtualEthernetInterfacePoint_AdministrativeState, EnumerationAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, false, false, 1),
			2: ByteField(VirtualEthernetInterfacePoint_OperationalState, EnumerationAttributeType, 0x4000, 0, mapset.NewSetWith(Read), true, true, false, 2),
			3: MultiByteField(VirtualEthernetInterfacePoint_InterdomainName, StringAttributeType, 0x2000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 3),
			4: Uint16Field(VirtualEthernetInterfacePoint_TcpUdpPointer, PointerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, Write), false, true, false, 4),
			5: Uint16Field(VirtualEthernetInterfacePoint_IanaAssignedPort, UnsignedIntegerAttributeType, 0x0800, 65535, mapset.NewSetWith(Read), false, false, false, 5),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "Connecting function fail",
		},
	}
}

// NewVirtualEthernetInterfacePoint (class ID 329) creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from or transmitted to the OMCC.
func NewVirtualEthernetInterfacePoint(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(*virtualethernetinterfacepointBME, params...)
}
