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

// MacBridgePortIcmpv6ProcessPreAssignTableClassID is the 16-bit ID for the OMCI
// Managed entity MAC bridge port ICMPv6 process pre-assign table
const MacBridgePortIcmpv6ProcessPreAssignTableClassID = ClassID(348) // 0x015c

var macbridgeporticmpv6processpreassigntableBME *ManagedEntityDefinition

// MacBridgePortIcmpv6ProcessPreAssignTable (Class ID: #348 / 0x015c)
//	This ME provides an approach to ICMPv6 message processing configuration to those ONUs that
//	support IPv6 awareness. For every message, the MAC bridge port ICMPv6 process pre-assign table
//	can designate a forward, discard or snoop operation. The ONU creates or deletes an instance of
//	this ME automatically upon creation or deletion of a MAC bridge port configuration data ME.
//
//	The MAC bridge port ICMPv6 process pre-assign table ME filters layer 2 traffic between the UNI
//	and ANI. The operation of this ME is completely independent of the operation and traffic
//	generated or received by a possible IPv6 host config data ME.
//
//	Relationships
//		An instance of this ME is associated with an instance of a MAC bridge port configuration data
//		ME.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. Through an identical ID, this ME is
//			implicitly linked to an instance of the MAC bridge port configuration data ME. (R) (mandatory)
//			(2-bytes)
//
//			The following nine attributes have similar definitions. Each permits the OLT to specify ICMPv6
//			as the next header in the IPv6 header and various types in the ICMPv6 header, and whether
//			traffic of the specified type is forwarded, discarded or snooped, in upstream and downstream
//			directions separately. The bits of each attribute are assigned as follows.
//
//			The initial value of each attribute is given in the last column of the table.
//
//		Icmpv6 Error Messages Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Icmpv6 Informational Messages Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Router Solicitation Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Router Advertisement Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Neighbour Solicitation Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Neighbour Advertisement Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Redirect Processing
//			(R,-W) (mandatory) (1-byte)
//
//		Multicast Listener Query Processing
//			(R,-W) (mandatory) (1-byte)
//
//			NOTE - If the ONU participates in multicast services, MLD queries should be controlled through
//			the multicast operations profile ME. In such a case, it is strongly recommended not to provision
//			the downstream direction of the multicast listener query processing attribute to any value other
//			than forwarding.
//
//		Unknown Icmpv6 Processing
//			(R,-W) (mandatory) (1-byte)
//
type MacBridgePortIcmpv6ProcessPreAssignTable struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	macbridgeporticmpv6processpreassigntableBME = &ManagedEntityDefinition{
		Name:    "MacBridgePortIcmpv6ProcessPreAssignTable",
		ClassID: 348,
		MessageTypes: mapset.NewSetWith(
			Get,
		),
		AllowedAttributeMask: 0xff80,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: ByteField("Icmpv6ErrorMessagesProcessing", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, false, false, 1),
			2: ByteField("Icmpv6InformationalMessagesProcessing", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, Write), false, false, false, 2),
			3: ByteField("RouterSolicitationProcessing", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, Write), false, false, false, 3),
			4: ByteField("RouterAdvertisementProcessing", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, Write), false, false, false, 4),
			5: ByteField("NeighbourSolicitationProcessing", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, Write), false, false, false, 5),
			6: ByteField("NeighbourAdvertisementProcessing", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, Write), false, false, false, 6),
			7: ByteField("RedirectProcessing", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, Write), false, false, false, 7),
			8: ByteField("MulticastListenerQueryProcessing", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, Write), false, false, false, 8),
			9: ByteField("UnknownIcmpv6Processing", UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read, Write), false, false, false, 9),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

// NewMacBridgePortIcmpv6ProcessPreAssignTable (class ID 348) 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 NewMacBridgePortIcmpv6ProcessPreAssignTable(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(*macbridgeporticmpv6processpreassigntableBME, params...)
}
