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

// RtpProfileDataClassID is the 16-bit ID for the OMCI
// Managed entity RTP profile data
const RtpProfileDataClassID ClassID = ClassID(143)

var rtpprofiledataBME *ManagedEntityDefinition

// RtpProfileData (class ID #143)
//	This ME configures RTP. It is conditionally required for ONUs that offer VoIP service. If a non-
//	OMCI interface is used to manage VoIP, this ME is unnecessary.
//
//	An instance of this ME is created and deleted by the OLT. An RTP profile is needed for each
//	unique set of attributes.
//
//	Relationships
//		An instance of this ME may be associated with one or more VoIP media profile MEs.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. (R, setbycreate)
//			(mandatory) (2-bytes)
//
//		Local Port Min
//			Local port min: This attribute defines the base UDP port that should be used by RTP for voice
//			traffic. The recommended default is 50000 (R,-W, set-by-create) (mandatory) (2-bytes)
//
//		Local Port Max
//			Local port max: This attribute defines the highest UDP port used by RTP for voice traffic. The
//			value must be greater than the local port minimum. The value 0 specifies that the local port
//			maximum be equal to the local port minimum. (R,-W, set-by-create) (optional) (2-bytes)
//
//		Dscp Mark
//			DSCP mark:	Diffserv code point to be used for outgoing RTP packets for this profile. The
//			recommended default value is expedited forwarding (EF)-= 0x2E. (R,-W, setbycreate) (mandatory)
//			(1-byte)
//
//		Piggyback Events
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Tone Events
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Dtmf Events
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Cas Events
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Ip Host Config Pointer
//			IP host config pointer: This optional pointer associates the bearer (voice) flow with an IP host
//			config data or IPv6 host config data ME. If this attribute is not present or is not populated
//			with a valid pointer value, the bearer flow uses the same IP stack that is used for signalling,
//			indicated by the TCP/UDP pointer in the associated SIP agent or MGC config data. The default
//			value is 0xFFFF, a null pointer. (R,-W) (optional) (2-bytes)
//
type RtpProfileData struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	rtpprofiledataBME = &ManagedEntityDefinition{
		Name:    "RtpProfileData",
		ClassID: 143,
		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("LocalPortMin", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2: Uint16Field("LocalPortMax", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 2),
			3: ByteField("DscpMark", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 3),
			4: ByteField("PiggybackEvents", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5: ByteField("ToneEvents", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 5),
			6: ByteField("DtmfEvents", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 6),
			7: ByteField("CasEvents", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 7),
			8: Uint16Field("IpHostConfigPointer", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, Write), false, true, false, 8),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

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