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

// GemInterworkingTerminationPointClassID is the 16-bit ID for the OMCI
// Managed entity GEM interworking termination point
const GemInterworkingTerminationPointClassID = ClassID(266) // 0x010a

var geminterworkingterminationpointBME *ManagedEntityDefinition

// GemInterworkingTerminationPoint (Class ID: #266 / 0x010a)
//	An instance of this ME represents a point in the ONU where the IW of a bearer service (usually
//	Ethernet) to the GEM layer takes place. At this point, GEM packets are generated from the bearer
//	bit stream (e.g., Ethernet) or the bearer bit stream is reconstructed from GEM packets.
//
//	Instances of this ME are created and deleted by the OLT.
//
//	Relationships
//		One instance of this ME exists for each transformation of a data stream into GEM frames and vice
//		versa.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. (R, setbycreate) (mandatory)
//			(2-bytes)
//
//		Gem Port Network Ctp Connectivity Pointer
//			This attribute points to an instance of the GEM port network CTP. (R,-W, setbycreate)
//			(mandatory) (2-bytes)
//
//		Interworking Option
//			This attribute identifies the type of non-GEM function that is being interworked. The options
//			are as follows.
//
//			0	Circuit-emulated TDM
//
//			1	MAC bridged LAN
//
//			2	Reserved
//
//			3	Reserved
//
//			4	Video return path
//
//			5	IEEE 802.1p mapper
//
//			6	Downstream broadcast
//
//			7	MPLS PW TDM service
//
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Service Profile Pointer
//			This attribute points to an instance of a service profile:
//
//			CES service profile	if IW option-=-0
//
//			MAC bridge service profile	if IW option-=-1
//
//			Video return path service profile	if IW option-=-4
//
//			IEEE 802.1p mapper service profile	if IW option-=-5
//
//			Null pointer	if IW option-=-6
//
//			CES service profile	if IW option-=-7
//
//			(R,-W, setbycreate) (mandatory) (2-bytes)
//
//			NOTE - The video return path (VRP) service profile is defined in [ITU-T G.984.4].
//
//		Interworking Termination Point Pointer
//			This attribute is used for the CES and IEEE 802.1p mapper service without a MAC bridge.
//			Depending on the service provided, it points to the associated instance of the following MEs:
//
//			PPTP CES UNI
//
//			Logical N * 64 kbit/s sub-port CTP
//
//			PPTP Ethernet UNI
//
//			In all other GEM services, the relationship between the related service TP and this GEM IW TP is
//			derived from other ME relations; this attribute is set to a null pointer and not used. (R,-W,
//			setbycreate) (mandatory) (2-bytes)
//
//		Pptp Counter
//			This value reports the number of PPTP ME instances associated with this GEM IW TP. (R)
//			(optional) (1-byte)
//
//		Operational State
//			This attribute indicates whether the ME is capable of performing its function. Valid values are
//			enabled (0) and disabled (1). (R) (optional) (1-byte)
//
//		Gal Profile Pointer
//			5	GAL Ethernet profile for IEEE 802.1p mapper
//
//			6	Null pointer
//
//			7	Null pointer
//
//			(R,-W, setbycreate) (mandatory) (2-bytes)
//
//			This attribute points to an instance of the GAL profile. The relationship between the IW option
//			and the related GAL profile is as follows.
//
//			Interworking option	GAL profile type
//
//			0	Null pointer
//
//			1	GAL Ethernet profile
//
//			3	GAL Ethernet profile for data service
//
//			4	GAL Ethernet profile for video return path
//
//		Gal Loopback Configuration
//			This attribute sets the loopback configuration when using GEM mode:
//
//			0	No loopback
//
//			1	Loopback of downstream traffic after GAL
//
//			The default value of this attribute is 0. When the IW option is 6 (downstream broadcast), this
//			attribute is not used. (R,-W) (mandatory) (1-byte)
//
type GemInterworkingTerminationPoint struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	geminterworkingterminationpointBME = &ManagedEntityDefinition{
		Name:    "GemInterworkingTerminationPoint",
		ClassID: 266,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xff00,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1: Uint16Field("GemPortNetworkCtpConnectivityPointer", PointerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2: ByteField("InterworkingOption", EnumerationAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3: Uint16Field("ServiceProfilePointer", PointerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 3),
			4: Uint16Field("InterworkingTerminationPointPointer", PointerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5: ByteField("PptpCounter", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read), false, true, false, 5),
			6: ByteField("OperationalState", EnumerationAttributeType, 0x0400, 0, mapset.NewSetWith(Read), true, true, false, 6),
			7: Uint16Field("GalProfilePointer", PointerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 7),
			8: ByteField("GalLoopbackConfiguration", EnumerationAttributeType, 0x0100, 0, mapset.NewSetWith(Read, Write), false, false, false, 8),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "Deprecated",
		},
	}
}

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