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

// Dot1AgDefaultMdLevelClassID is the 16-bit ID for the OMCI
// Managed entity Dot1ag default MD level
const Dot1AgDefaultMdLevelClassID ClassID = ClassID(301)

var dot1agdefaultmdlevelBME *ManagedEntityDefinition

// Dot1AgDefaultMdLevel (class ID #301)
//	The collection of the functionality called a maintenance half-function (MHF) is not explicitly
//	modelled as a ME by either [IEEE 802.1ag] or the OMCI. The ONU automatically creates MHFs
//	according to parameters specified in a dot1ag MD or a dot1ag MA ME; the dot1ag default MD level
//	ME catches the corner cases not covered by other MEs, specifically VLANs not included by any
//	defined MA.
//
//	The dot1ag default MD level comprises a configurable table, each entry of which specifies
//	default MHF functionality for some set of VLANs. Once a set of VLANs is defined, operations to
//	different table entries or to dot1ag MAs that conflict with the set membership should be denied.
//	In addition, catch-all attributes are defined to specify MHF functionality when there is no
//	match to either a table entry or an MA.
//
//	Relationships
//		An ONU that supports [IEEE 802.1ag] automatically creates one instance of this ME for each MAC
//		bridge or IEEE 802.1p mapper, depending on the ONU's provisioning model. It should not create an
//		instance for an IEEE 802.1p mapper that is associated with a MAC bridge.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies an instance of this ME. Through an
//			identical ID, this ME is implicitly linked to an instance of the MAC bridge service profile ME
//			or an IEEE 802.1p mapper ME. It is expected that an ONU will implement CFM on bridges or on
//			IEEE-802.1p mappers, but not both, depending on its provisioning model. For precision, the
//			reference is disambiguated by the value of the layer 2 type pointer attribute. (R) (mandatory)
//			(2-bytes)
//
//		Layer 2 Type
//			Layer 2 type: This attribute specifies whether the dot1ag default MD level ME is associated with
//			a MAC bridge service profile (value 0) or an IEEE 802.1p mapper (value-1). (R) (mandatory)
//			(1-byte)
//
//		Catchall Level
//			Catchall level: This attribute ranges from 0..7 and specifies the MD level of MHFs created when
//			no specific match is found. (R,-W) (mandatory) (1-byte)
//
//		Catchall Mhf Creation
//			(R,-W) (mandatory) (1-byte)
//
//		Catchall Sender Id Permission
//			Catchall sender ID permission: This attribute determines the contents of the sender ID TLV
//			included in CFM messages transmitted by MPs when no more specific match is found. This attribute
//			is identical to that defined in the description of the dot1ag MD ME (i.e., excluding code point
//			5, defer). (R,-W) (mandatory) (1-byte)
//
//		Default Md Level Table
//			(R,-W) (mandatory) (29-bytes * N entries)
//
type Dot1AgDefaultMdLevel struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	dot1agdefaultmdlevelBME = &ManagedEntityDefinition{
		Name:    "Dot1AgDefaultMdLevel",
		ClassID: 301,
		MessageTypes: mapset.NewSetWith(
			Get,
			GetNext,
			Set,
		),
		AllowedAttributeMask: 0xf800,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: ByteField("Layer2Type", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read), false, false, false, 1),
			2: ByteField("CatchallLevel", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, Write), false, false, false, 2),
			3: ByteField("CatchallMhfCreation", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, Write), false, false, false, 3),
			4: ByteField("CatchallSenderIdPermission", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, Write), false, false, false, 4),
			5: TableField("DefaultMdLevelTable", TableAttributeType, 0x0800, TableInfo{nil, 29}, mapset.NewSetWith(Read, Write), false, false, false, 5),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

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