/*
 * 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 = ClassID(155)

var mgcconfigdataBME *ManagedEntityDefinition

// MgcConfigData (class ID #155)
//	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
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. (R, setbycreate)
//			(mandatory) (2-bytes)
//
//		Primary Mgc
//			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
//			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
//			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
//			The default value is recommended to be 0. (R,-W, setbycreate) (mandatory) (1-byte)
//
//		Maximum Retry Time
//			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
//			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
//			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
//			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
//			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
//			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...)
}
