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

// PhysicalPathTerminationPointXdslUniPart2ClassID is the 16-bit ID for the OMCI
// Managed entity Physical path termination point xDSL UNI part 2
const PhysicalPathTerminationPointXdslUniPart2ClassID = ClassID(99) // 0x0063

var physicalpathterminationpointxdslunipart2BME *ManagedEntityDefinition

// PhysicalPathTerminationPointXdslUniPart2 (Class ID: #99 / 0x0063)
//	This ME represents the point in the ONU where physical paths terminate on an xDSL CO modem
//	(xTU-C). Standards and chip sets support several forms of DSL, including VDSL2, and the xDSL ME
//	family is used for all of them, with specific extensions for technology variations.
//
//	The ONU creates or deletes an instance of this ME at the same time it creates or deletes the
//	corresponding PPTP xDSL UNI part 1.
//
//	Relationships
//		An instance of this ME is associated with each instance of a PPTP xDSL UNI part 1.
//
//	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 PPTP xDSL UNI part 1. (R) (mandatory) (2-bytes)
//
//			Each of the following eight attributes is a pointer to an xDSL channel configuration profile ME.
//			In each case, the default value 0, set when the ME is auto-created, is a null pointer.
//
//		Xdsl Channel Configuration Profile For Bearer Channel 0 Downstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 1 Downstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 2 Downstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 3 Downstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 0 Upstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 1 Upstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 2 Upstream
//				(R,-W) (optional) (2-bytes)
//
//		Xdsl Channel Configuration Profile For Bearer Channel 3 Upstream
//				(R,-W) (optional) (2-bytes)
//
type PhysicalPathTerminationPointXdslUniPart2 struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel0Downstream = "XdslChannelConfigurationProfileForBearerChannel0Downstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel1Downstream = "XdslChannelConfigurationProfileForBearerChannel1Downstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel2Downstream = "XdslChannelConfigurationProfileForBearerChannel2Downstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel3Downstream = "XdslChannelConfigurationProfileForBearerChannel3Downstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel0Upstream = "XdslChannelConfigurationProfileForBearerChannel0Upstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel1Upstream = "XdslChannelConfigurationProfileForBearerChannel1Upstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel2Upstream = "XdslChannelConfigurationProfileForBearerChannel2Upstream"
const PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel3Upstream = "XdslChannelConfigurationProfileForBearerChannel3Upstream"

func init() {
	physicalpathterminationpointxdslunipart2BME = &ManagedEntityDefinition{
		Name:    "PhysicalPathTerminationPointXdslUniPart2",
		ClassID: PhysicalPathTerminationPointXdslUniPart2ClassID,
		MessageTypes: mapset.NewSetWith(
			Get,
			Set,
		),
		AllowedAttributeMask: 0xff00,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel0Downstream, UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, true, false, 1),
			2: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel1Downstream, UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, Write), false, true, false, 2),
			3: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel2Downstream, UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, Write), false, true, false, 3),
			4: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel3Downstream, UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, Write), false, true, false, 4),
			5: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel0Upstream, UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, Write), false, true, false, 5),
			6: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel1Upstream, UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, Write), false, true, false, 6),
			7: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel2Upstream, UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, Write), false, true, false, 7),
			8: Uint16Field(PhysicalPathTerminationPointXdslUniPart2_XdslChannelConfigurationProfileForBearerChannel3Upstream, UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, Write), false, true, false, 8),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

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