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

func init() {
	dot1xconfigurationprofileBME = &ManagedEntityDefinition{
		Name:    "Dot1XConfigurationProfile",
		ClassID: 291,
		MessageTypes: mapset.NewSetWith(
			Get,
			Set,
		),
		AllowedAttributeMask: 0xffc0,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1:  Uint16Field("CircuitIdPrefix", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, false, false, 1),
			2:  ByteField("FallbackPolicy", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, Write), false, false, false, 2),
			3:  Uint16Field("AuthServer1", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, Write), false, false, false, 3),
			4:  MultiByteField("SharedSecretAuth1", OctetsAttributeType, 0x1000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, false, false, 4),
			5:  Uint16Field("AuthServer2", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, Write), false, true, false, 5),
			6:  MultiByteField("SharedSecretAuth2", OctetsAttributeType, 0x0400, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 6),
			7:  Uint16Field("AuthServer3", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, Write), false, true, false, 7),
			8:  MultiByteField("SharedSecretAuth3", OctetsAttributeType, 0x0100, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 8),
			9:  Uint32Field("OltProxyAddress", UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read, Write), false, true, false, 9),
			10: Uint16Field("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...)
}
