/*
 * 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 = ClassID(348)

var macbridgeporticmpv6processpreassigntableBME *ManagedEntityDefinition

// MacBridgePortIcmpv6ProcessPreAssignTable (class ID #348)
//	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
//			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)
//
//		Icmpv6 Error Messages Processing
//			ICMPv6 error messages processing:	(R,-W) (mandatory) (1-byte)
//
//		Icmpv6 Informational Messages Processing
//			ICMPv6 informational messages processing:	(R,-W) (mandatory) (1-byte)
//
//		Router Solicitation Processing
//			Router solicitation processing:	(R,-W) (mandatory) (1-byte)
//
//		Router Advertisement Processing
//			Router advertisement processing:	(R,-W) (mandatory) (1-byte)
//
//		Neighbour Solicitation Processing
//			Neighbour solicitation processing:	(R,-W) (mandatory) (1-byte)
//
//		Neighbour Advertisement Processing
//			Neighbour advertisement processing:	(R,-W) (mandatory) (1-byte)
//
//		Redirect Processing
//			Redirect processing:	(R,-W) (mandatory) (1-byte)
//
//		Multicast Listener Query Processing
//			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
//			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...)
}
