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

// TContClassID is the 16-bit ID for the OMCI
// Managed entity T-CONT
const TContClassID ClassID = ClassID(262)

var tcontBME *ManagedEntityDefinition

// TCont (class ID #262)
//	An instance of the traffic container ME T-CONT represents a logical connection group associated
//	with a G-PON PLOAM layer alloc-ID. A T-CONT can accommodate GEM packets in priority queues or
//	traffic schedulers that exist in the GEM layer.
//
//	The ONU autonomously creates instances of this ME. The OLT can discover the number of TCONT
//	instances via the ANI-G ME. When the ONU's MIB is reset or created for the first time, all
//	supported T-CONTs are created. The OLT provisions alloc-IDs to the ONU via the PLOAM channel.
//	Via the OMCI, the OLT must then set the alloc-ID attributes in the T-CONTs that it wants to
//	activate for user traffic, to create the appropriate association with the allocation ID in the
//	PLOAM channel. There should be a one-to-one relationship between allocation IDs and T-CONT MEs;
//	the connection of multiple T-CONTs to a single allocation ID is undefined.
//
//	The allocation ID that matches the ONU-ID itself is defined to be the default alloc-ID. This
//	allocID is used to carry the OMCC. The default alloc-ID can also be used to carry user traffic,
//	and hence can be assigned to one of the T-CONT MEs. However, this OMCI relationship only
//	pertains to user traffic, and the OMCC relationship is unaffected. It can also be true that the
//	OMCC is not contained in any T-CONT ME construct; rather, that the OMCC remains outside of the
//	OMCI, and that the OMCI is not used to manage the OMCC in any way. Multiplexing of the OMCC and
//	user data in GPON systems is discussed in clause B.2.4.
//
//	Relationships
//		One or more instances of this ME are associated with an instance of a circuit pack that supports
//		a PON interface function, or with the ONU-G itself.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. This 2-byte
//			number indicates the physical capability that realizes the TCONT. It may be represented as
//			0xSSBB, where SS indicates the slot ID that contains this T-CONT (0 for the ONU as a whole), and
//			BB is the TCONT ID, numbered by the ONU itself. T-CONTs are numbered in ascending order, with
//			the range 0..255 in each slot. (R) (mandatory) (2-bytes)
//
//		Alloc_Id
//			Alloc-ID:	This attribute links the T-CONT with the alloc-ID assigned by the OLT in the
//			assign_alloc-ID PLOAM message. The respective TC layer specification should be referenced for
//			the legal values for that system. Prior to the setting of this attribute by the OLT, this
//			attribute has an unambiguously unusable initial value, namely the value 0x00FF or 0xFFFF for
//			ITU-T G.984 systems, and the value 0xFFFF for all other ITU-T GTC based PON systems. (R,-W)
//			(mandatory) (2-bytes)
//
//		Deprecated
//			Deprecated:	The ONU should set this attribute to the value 1, and the OLT should ignore it. (R)
//			(mandatory) (1-byte)
//
//		Policy
//			NOTE - This attribute is read-only, unless otherwise specified by the QoS configuration
//			flexibility attribute of the ONU2-G ME. If flexible configuration is not supported, the ONU
//			should reject an attempt to set it with a parameter error result-reason code.
//
type TCont struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	tcontBME = &ManagedEntityDefinition{
		Name:    "TCont",
		ClassID: 262,
		MessageTypes: mapset.NewSetWith(
			Get,
			Set,
		),
		AllowedAttributeMask: 0xe000,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: Uint16Field("AllocId", UnsignedIntegerAttributeType, 0x8000, 65535, mapset.NewSetWith(Read, Write), false, false, false, 1),
			2: ByteField("Deprecated", UnsignedIntegerAttributeType, 0x4000, 1, mapset.NewSetWith(Read), false, false, true, 2),
			3: ByteField("Policy", EnumerationAttributeType, 0x2000, 0, mapset.NewSetWith(Read, Write), false, false, false, 3),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

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