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

// MgcConfigDataClassID is the 16-bit ID for the OMCI
// Managed entity MGC config data
const MgcConfigDataClassID = ClassID(155) // 0x009b

var mgcconfigdataBME *ManagedEntityDefinition

// MgcConfigData (Class ID: #155 / 0x009b)
//	The MGC config data ME defines the MGC configuration associated with an MG subscriber. It is
//	conditionally required for ONUs that support ITU-T H.248 VoIP services. If a non-OMCI interface
//	is used to manage VoIP signalling, this ME is unnecessary.
//
//	Instances of this ME are created and deleted by the OLT.
//
//	Relationships
//		An instance of this ME may be associated with one or more VoIP voice CTP MEs.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. (R, setbycreate) (mandatory)
//			(2-bytes)
//
//		Primary Mgc
//			This attribute points to a network address ME that contains the name (IP-address or resolved
//			name) of the primary MGC that controls the signalling messages. The port is optional and
//			defaults to 2944 for text message formats and 2955 for binary message formats. (R,-W,
//			setbycreate) (mandatory) (2-bytes)
//
//		Secondary Mgc
//			This attribute points to a network address ME that contains the name (IP-address or resolved
//			name) of the secondary or backup MGC that controls the signalling messages. The port is optional
//			and defaults to 2944 for text message formats and 2955 for binary message formats. (R,-W,
//			setbycreate) (mandatory) (2-bytes)
//
//		Tcp_Udp Pointer
//			TCP/UDP pointer: This attribute points to the TCP/UDP config data ME to be used for
//			communication with the MGC. (R,-W, setbycreate) (mandatory) (2-bytes)
//
//		Version
//			This integer attribute reports the version of the Megaco protocol in use. The ONU should deny an
//			attempt by the OLT to set or create a value that it does not support. The value 0 indicates that
//			no particular version is specified. (R,-W, setbycreate) (mandatory) (1-byte)
//
//		Message Format
//			This attribute defines the message format. Valid values are as follows.
//
//			0	Text long
//
//			1	Text short
//
//			2	Binary
//
//			The default value is recommended to be 0. (R,-W, setbycreate) (mandatory) (1-byte)
//
//		Maximum Retry Time
//			This attribute specifies the maximum retry time for MGC transactions, in seconds. The default
//			value 0 specifies vendor-specific implementation. (R,-W) (optional) (2-bytes)
//
//		Maximum Retry Attempts
//			This attribute specifies the maximum number of times a message is retransmitted to the MGC. The
//			recommended default value 0 specifies vendor-specific implementation. (R,-W, setbycreate)
//			(optional) (2-bytes)
//
//		Service Change Delay
//			This attribute specifies the service status delay time for changes in line service status. This
//			attribute is specified in seconds. The default value 0 specifies no delay. (R,-W) (optional)
//			(2-bytes)
//
//		Termination Id Base
//			This attribute specifies the base string for the ITU-T H.248 physical termination ID(s) for this
//			ONU. This string is intended to uniquely identify an ONU. Vendor-specific termination
//			identifiers (port IDs) are optionally added to this string to uniquely identify a termination on
//			a specific ONU. (R,-W) (optional) (25-bytes)
//
//		Softswitch
//			This attribute identifies the gateway softswitch vendor. The format is four ASCII coded
//			alphabetic characters [A..Z] as defined in [ATIS0300220]. A value of four null bytes indicates
//			an unknown or unspecified vendor. (R,-W, setbycreate) (mandatory) (4-bytes)
//
//		Message Id Pointer
//			This attribute points to a large string whose value specifies the message identifier string for
//			ITU-T H.248 messages originated by the ONU. (R, W, setbycreate) (optional) (2 bytes)
//
type MgcConfigData struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	mgcconfigdataBME = &ManagedEntityDefinition{
		Name:    "MgcConfigData",
		ClassID: 155,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xffe0,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1:  Uint16Field("PrimaryMgc", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2:  Uint16Field("SecondaryMgc", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3:  Uint16Field("TcpUdpPointer", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 3),
			4:  ByteField("Version", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5:  ByteField("MessageFormat", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 5),
			6:  Uint16Field("MaximumRetryTime", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, Write), false, true, false, 6),
			7:  Uint16Field("MaximumRetryAttempts", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 7),
			8:  Uint16Field("ServiceChangeDelay", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, Write), false, true, false, 8),
			9:  MultiByteField("TerminationIdBase", OctetsAttributeType, 0x0080, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 9),
			10: Uint32Field("Softswitch", UnsignedIntegerAttributeType, 0x0040, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 10),
			11: Uint16Field("MessageIdPointer", UnsignedIntegerAttributeType, 0x0020, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 11),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "Timeout",
		},
	}
}

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