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

// TrafficDescriptorClassID is the 16-bit ID for the OMCI
// Managed entity Traffic descriptor
const TrafficDescriptorClassID = ClassID(280) // 0x0118

var trafficdescriptorBME *ManagedEntityDefinition

// TrafficDescriptor (Class ID: #280 / 0x0118)
//	The traffic descriptor is a profile that allows for traffic management. A priority controlled
//	ONU can point from a MAC bridge port configuration data ME to a traffic descriptor in order to
//	implement traffic management (marking, policing). A rate controlled ONU can point to a traffic
//	descriptor from either a MAC bridge port configuration data ME or a GEM port network CTP to
//	implement traffic management (marking, shaping).
//
//	Packets are determined to be green, yellow or red as a function of the ingress packet rate and
//	the settings in this ME. The colour indicates drop precedence (eligibility), subsequently used
//	by the priority queue ME to drop packets conditionally during congestion conditions. Packet
//	colour is also used by the optional mode 1 DBA status reporting function described in [ITUT
//	G.984.3]. Red packets are dropped immediately. Yellow packets are marked as drop eligible, and
//	green packets are marked as not drop eligible, according to the egress colour marking attribute.
//
//	The algorithm used to determine the colour marking is specified by the meter type attribute. If
//	[bIETF RFC 4115] is used, then:
//
//	CIR4115-=-CIR
//
//	EIR4115-=-PIR - CIR (EIR: excess information rate)
//
//	CBS4115-=-CBS
//
//	EBS4115-=-PBS - CBS.
//
//	Relationships
//		This ME is associated with a GEM port network CTP or a MAC bridge port configuration data ME.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. (R, setbycreate) (mandatory)
//			(2-bytes)
//
//		Cir
//			This attribute specifies the committed information rate, in bytes per second. The default is 0.
//			(R,-W, setbycreate) (optional) (4-bytes)
//
//		Pir
//			This attribute specifies the peak information rate, in bytes per second. The default value 0
//			accepts the ONU's factory policy. (R,-W, setbycreate) (optional) (4-bytes)
//
//		Cbs
//			This attribute specifies the committed burst size, in bytes. The default is 0. (R,-W,
//			setbycreate) (optional) (4-bytes)
//
//		Pbs
//			This attribute specifies the peak burst size, in bytes. The default value 0 accepts the ONU's
//			factory policy. (R,-W, setbycreate) (optional) (4-bytes)
//
//		Colour Mode
//			This attribute specifies whether the colour marking algorithm considers pre-existing marking on
//			ingress packets (colour-aware) or ignores it (colour-blind). In colour-aware mode, packets can
//			only be demoted (from green to yellow or red, or from yellow to red). The default value is 0.
//
//			0	Colour-blind
//
//			1	Colour-aware
//
//			(R,-W, setbycreate) (optional) (1-byte)
//
//		Ingress Colour Marking
//			This attribute is meaningful in colour-aware mode. It identifies how pre-existing drop
//			precedence is marked on ingress packets. For DEI and PCP marking, a drop eligible indicator is
//			equivalent to yellow; otherwise, the colour is green. For DSCP AF marking, the lowest drop
//			precedence is equivalent to green; otherwise, the colour is yellow. The default value is 0.
//
//			0	No marking (ignore ingress marking)
//
//			2	DEI [IEEE 802.1ad]
//
//			3	PCP 8P0D [IEEE 802.1ad]
//
//			4	PCP 7P1D [IEEE 802.1ad]
//
//			5	PCP 6P2D [IEEE 802.1ad]
//
//			6	PCP 5P3D [IEEE 802.1ad]
//
//			7	DSCP AF class [IETF RFC 2597]
//
//			(R,-W, setbycreate) (optional) (1-byte)
//
//		Egress Colour Marking
//			2	DEI [IEEE 802.1ad]
//
//			3	PCP 8P0D [IEEE 802.1ad]
//
//			4	PCP 7P1D [IEEE 802.1ad]
//
//			5	PCP 6P2D [IEEE 802.1ad]
//
//			6	PCP 5P3D [IEEE 802.1ad]
//
//			7	DSCP AF class [IETF RFC 2597]
//
//			(R,-W, setbycreate) (optional) (1-byte)
//
//			This attribute specifies how drop precedence is to be marked by the ONU on egress packets. If
//			set to internal marking only, the externally visible packet contents are not modified, but the
//			packet is identified in a vendor-specific local way that indicates its colour to the priority
//			queue ME. It is possible for the egress marking to differ from the ingress marking; for example,
//			ingress PCP marking could be translated to DEI egress marking. The default value is 0.
//
//			0	No marking
//
//			1	Internal marking only
//
//		Meter Type
//			This attribute specifies the algorithm used to determine the colour of the packet. The default
//			value is 0.
//
//			0	Not specified
//
//			1	[b-IETF RFC 4115]
//
//			2	[b-IETF RFC 2698]
//
//			(R, setbycreate) (optional) (1-byte)
//
type TrafficDescriptor struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	trafficdescriptorBME = &ManagedEntityDefinition{
		Name:    "TrafficDescriptor",
		ClassID: 280,
		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: Uint32Field("Cir", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 1),
			2: Uint32Field("Pir", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 2),
			3: Uint32Field("Cbs", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 3),
			4: Uint32Field("Pbs", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 4),
			5: ByteField("ColourMode", EnumerationAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 5),
			6: ByteField("IngressColourMarking", EnumerationAttributeType, 0x0400, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 6),
			7: ByteField("EgressColourMarking", EnumerationAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 7),
			8: ByteField("MeterType", EnumerationAttributeType, 0x0100, 0, mapset.NewSetWith(Read, SetByCreate), false, true, false, 8),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

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