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

// Dot1XConfigurationProfileClassID is the 16-bit ID for the OMCI
// Managed entity Dot1X configuration profile
const Dot1XConfigurationProfileClassID = ClassID(291) // 0x0123

var dot1xconfigurationprofileBME *ManagedEntityDefinition

// Dot1XConfigurationProfile (Class ID: #291 / 0x0123)
//	An instance of this ME represents a set of attributes that control an ONU's 802.1X operation
//	with regard to IEEE 802 services. An instance of this ME is created by the ONU if it is capable
//	of supporting [IEEE 802.1X] authentication of CPE.
//
//	Relationships
//		One instance of this ME governs the ONU's 802.1X CPE authentication behaviour.
//
//	Attributes
//		Managed Entity Id
//			This attribute provides a unique number for each instance of this ME. There is at most one
//			instance, number 0. (R) (mandatory) (2-bytes)
//
//		Circuit Id Prefix
//			This attribute is a pointer to a large string ME whose content appears as the prefix of the NAS
//			port ID in radius access-request messages. The remainder of the NAS port ID field is local
//			information (for example, slot-port, appended by the ONU itself). The default value of this
//			attribute is the null pointer 0. (R,-W) (mandatory) (2-bytes)
//
//		Fallback Policy
//			When set to 1 (deny), this attribute causes IEEE-802.1X conversations to fail when no external
//			authentication server is accessible, such that no Ethernet service is provided. The default
//			value 0 causes IEEE-802.1X conversations to succeed when no external authentication server is
//			accessible. (R,-W) (mandatory) (1-byte)
//
//		Auth Server 1
//			This attribute is a pointer to a large string ME that contains the URI of the first choice
//			radius authentication server. The value 0 indicates that no radius authentication server is
//			specified. (R,-W) (mandatory) (2-bytes)
//
//		Shared Secret Auth1
//			This attribute is the shared secret for the first radius authentication server. It is a null-
//			terminated character string. (R,-W) (mandatory) (25-bytes)
//
//			The following two pairs of attributes are defined in the same way:
//
//		Auth Server 2
//			(R,-W) (optional) (2-bytes)
//
//		Shared Secret Auth2
//			(R,-W) (optional) (25-bytes)
//
//		Auth Server 3
//			(R,-W) (optional) (2-bytes)
//
//		Shared Secret Auth3
//			(R,-W) (optional) (25-bytes)
//
//		Olt Proxy Address
//			This attribute indicates the IP address of a possible proxy at the OLT for IEEE-802.1X radius
//			messages. The default value 0.0.0.0 indicates that no proxy is required. (R,-W) (optional)
//			(4-bytes)
//
//		Calling Station Id Format
//			Radius messages initiated by the ONU contain a calling-station-ID field that is specified to be
//			the supplicant's MAC address in upper-case ASCII form, with bytes separated by a delimiter. This
//			attribute permits specification of the delimiter. (R,-W) (optional) (2-bytes)
//
//			Value	Meaning
//
//			0	ONU's internal default
//
//			1	Hyphen (-) delimiter
//
//			2	Colon (:) delimiter
//
//			3	No delimiter
//
//			0x20 - 0x7E	Use this value as the delimiter
//
//			0xF0 - 0xFE	Vendor-specific use
//
//			Other values are reserved.
//
type Dot1XConfigurationProfile struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const Dot1XConfigurationProfile_CircuitIdPrefix = "CircuitIdPrefix"
const Dot1XConfigurationProfile_FallbackPolicy = "FallbackPolicy"
const Dot1XConfigurationProfile_AuthServer1 = "AuthServer1"
const Dot1XConfigurationProfile_SharedSecretAuth1 = "SharedSecretAuth1"
const Dot1XConfigurationProfile_AuthServer2 = "AuthServer2"
const Dot1XConfigurationProfile_SharedSecretAuth2 = "SharedSecretAuth2"
const Dot1XConfigurationProfile_AuthServer3 = "AuthServer3"
const Dot1XConfigurationProfile_SharedSecretAuth3 = "SharedSecretAuth3"
const Dot1XConfigurationProfile_OltProxyAddress = "OltProxyAddress"
const Dot1XConfigurationProfile_CallingStationIdFormat = "CallingStationIdFormat"

func init() {
	dot1xconfigurationprofileBME = &ManagedEntityDefinition{
		Name:    "Dot1XConfigurationProfile",
		ClassID: Dot1XConfigurationProfileClassID,
		MessageTypes: mapset.NewSetWith(
			Get,
			Set,
		),
		AllowedAttributeMask: 0xffc0,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1:  Uint16Field(Dot1XConfigurationProfile_CircuitIdPrefix, UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, false, false, 1),
			2:  ByteField(Dot1XConfigurationProfile_FallbackPolicy, UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, Write), false, false, false, 2),
			3:  Uint16Field(Dot1XConfigurationProfile_AuthServer1, UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, Write), false, false, false, 3),
			4:  MultiByteField(Dot1XConfigurationProfile_SharedSecretAuth1, OctetsAttributeType, 0x1000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, false, false, 4),
			5:  Uint16Field(Dot1XConfigurationProfile_AuthServer2, UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, Write), false, true, false, 5),
			6:  MultiByteField(Dot1XConfigurationProfile_SharedSecretAuth2, OctetsAttributeType, 0x0400, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 6),
			7:  Uint16Field(Dot1XConfigurationProfile_AuthServer3, UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, Write), false, true, false, 7),
			8:  MultiByteField(Dot1XConfigurationProfile_SharedSecretAuth3, OctetsAttributeType, 0x0100, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 8),
			9:  Uint32Field(Dot1XConfigurationProfile_OltProxyAddress, UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read, Write), false, true, false, 9),
			10: Uint16Field(Dot1XConfigurationProfile_CallingStationIdFormat, UnsignedIntegerAttributeType, 0x0040, 0, mapset.NewSetWith(Read, Write), false, true, false, 10),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

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