/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 *
 * 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"

const OnuGClassId ClassID = ClassID(256)

var onugBME *ManagedEntityDefinition

// OnuG (class ID #256)
//	This ME represents the ONU as equipment. The ONU automatically creates an instance of this ME.
//	It assigns values to read-only attributes according to data within the ONU itself.
//
//	This ME has evolved from the ONT-G of [ITUT G.984.4].
//
//	Relationships
//		In ITU-T GTC based PON applications, all other MEs in this Recommendation are related directly
//		or indirectly to the ONU-G entity.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. There is only
//			one instance, number 0. (R) (mandatory) (2 bytes)
//
//		Vendor Id
//			Vendor ID:	This attribute identifies the vendor of the ONU. It is the same as the four most
//			significant bytes of the ONU serial number as specified in the respective transmission
//			convergence (TC) layer specification. (R) (mandatory) (4 bytes)
//
//		Version
//			Version:	This attribute identifies the version of the ONU as defined by the vendor. The
//			character value 0 indicates that version information is not available or applicable. (R)
//			(mandatory) (14 bytes)
//
//		Serial Number
//			Serial number: The serial number is unique for each ONU. It is defined in the respective TC
//			layer specification and contains the vendor ID and version number. The first four bytes are an
//			ASCII-encoded four-letter vendor ID. The second four bytes are a binary encoded serial number,
//			under the control of the ONU vendor. (R) (mandatory) (8 bytes)
//
//		Traffic Management Option
//			Upon ME instantiation, the ONU sets this attribute to the value that describes its
//			implementation. The OLT must adapt its model to conform to the ONU's selection. (R) (mandatory)
//			(1 byte)
//
//		Deprecated
//			Deprecated:	This attribute is not used. If it is present, it should be set to 0. (R) (optional)
//			(1 byte)
//
//		Battery Backup
//			Battery backup: This Boolean attribute controls whether the ONU performs backup battery
//			monitoring (assuming it is capable of doing so). False disables battery alarm monitoring; true
//			enables battery alarm monitoring. (R, W) (mandatory) (1 byte)
//
//		Administrative State
//			Administrative state: This attribute locks (1) and unlocks (0) the functions performed by the
//			ONU as an entirety. Administrative state is further described in clause A.1.6. (R, W)
//			(mandatory) (1 byte)
//
//		Operational State
//			Operational state: This attribute reports whether the ME is currently capable of performing its
//			function. Valid values are enabled (0) and disabled (1). (R) (optional) (1 byte)
//
//		Onu Survival Time
//			ONU survival time: This attribute indicates the minimum guaranteed time in milliseconds between
//			the loss of external power and the silence of the ONU. This does not include survival time
//			attributable to a backup battery. The value zero implies that the actual time is not known. (R)
//			(optional) (1 byte)
//
//		Logical Onu Id
//			Logical ONU ID: This attribute provides a way for the ONU to identify itself. It is a text
//			string, null terminated if it is shorter than 24 bytes, with a null default value. The mechanism
//			for creation or modification of this information is beyond the scope of this Recommendation, but
//			might include, for example, a web page displayed to a user. (R) (optional) (24 bytes)
//
//		Logical Password
//			Logical password: This attribute provides a way for the ONU to submit authentication
//			credentials. It is a text string, null terminated if it is shorter than 12 bytes, with a null
//			default value. The mechanism for creation or modification of this information is beyond the
//			scope of this Recommendation. (R) (optional) (12 bytes)
//
//		Credentials Status
//			Other values are reserved.
//
//		Extended Tc_Layer Options
//			(R) (optional) (2 bytes)
//
type OnuG struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	onugBME = &ManagedEntityDefinition{
		Name:    "OnuG",
		ClassID: 256,
		MessageTypes: mapset.NewSetWith(
			Get,
			Reboot,
			Set,
			SynchronizeTime,
			Test,
		),
		AllowedAttributeMask: 0XFFF8,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", 0, mapset.NewSetWith(Read), false, false, false, false, 0),
			1:  Uint32Field("VendorId", 0, mapset.NewSetWith(Read), false, false, false, false, 1),
			2:  MultiByteField("Version", 14, nil, mapset.NewSetWith(Read), false, false, false, false, 2),
			3:  Uint64Field("SerialNumber", 0, mapset.NewSetWith(Read), false, false, false, false, 3),
			4:  ByteField("TrafficManagementOption", 0, mapset.NewSetWith(Read), false, false, false, false, 4),
			5:  ByteField("Deprecated", 0, mapset.NewSetWith(Read), false, false, true, true, 5),
			6:  ByteField("BatteryBackup", 0, mapset.NewSetWith(Read, Write), false, false, false, false, 6),
			7:  ByteField("AdministrativeState", 0, mapset.NewSetWith(Read, Write), false, false, false, false, 7),
			8:  ByteField("OperationalState", 0, mapset.NewSetWith(Read), false, false, true, false, 8),
			9:  ByteField("OnuSurvivalTime", 0, mapset.NewSetWith(Read), false, false, true, false, 9),
			10: MultiByteField("LogicalOnuId", 24, nil, mapset.NewSetWith(Read), false, false, true, false, 10),
			11: MultiByteField("LogicalPassword", 12, nil, mapset.NewSetWith(Read), false, false, true, false, 11),
			12: ByteField("CredentialsStatus", 0, mapset.NewSetWith(Read, Write), false, false, true, false, 12),
			13: Uint16Field("ExtendedTcLayerOptions", 0, mapset.NewSetWith(Read), false, false, true, false, 13),
		},
	}
}

// NewOnuG (class ID 256 creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from the wire, about to be sent on the wire.
func NewOnuG(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(onugBME, params...)
}
