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

// RtpPseudowireParametersClassID is the 16-bit ID for the OMCI
// Managed entity RTP pseudowire parameters
const RtpPseudowireParametersClassID ClassID = ClassID(283)

var rtppseudowireparametersBME *ManagedEntityDefinition

// RtpPseudowireParameters (class ID #283)
//	If a pseudowire service uses RTP, the RTP pseudowire parameters ME provides configuration
//	information for the RTP layer. Instances of this ME are created and deleted by the OLT. The use
//	of RTP on a pseudowire is optional, and is determined by the existence of the RTP pseudowire
//	parameters ME.
//
//	Relationships
//		An instance of the RTP pseudowire parameters ME may exist for each pseudowire TP ME, to which it
//		is implicitly bound by a common ME ID.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. Through an
//			identical ID, this ME is implicitly linked to an instance of the pseudowire TP ME. (R,
//			setbycreate) (mandatory) (2-bytes)
//
//		Clock Reference
//			Clock reference: This attribute specifies the frequency of the common timing reference, in
//			multiples of 8 kHz. (R,-W, setbycreate) (mandatory) (2-bytes)
//
//		Rtp Timestamp Mode
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Ptype
//			PTYPE:	This attribute specifies the RTP payload type in the TDM to the PSN direction. It
//			comprises two 1-byte values. The first is for the payload channel, the second, for the optional
//			separate signalling channel. Assignable PTYPEs lie in the dynamic range 96..127. If signalling
//			is not transported in its own channel, the second value should be set to 0. (R,-W, setbycreate)
//			(mandatory) (2-bytes)
//
//		Ssrc
//			SSRC:	This attribute specifies the RTP synchronization source in the TDM to the PSN direction.
//			It comprises two 4-byte values. The first is for the payload channel, the second, for the
//			optional separate signalling channel. If signalling is not transported in its own channel, the
//			second value should be set to 0. (R,-W, setbycreate) (mandatory) (8-bytes)
//
//		Expected Ptype
//			Expected PTYPE: This attribute specifies the RTP payload type in the PSN to the TDM direction.
//			The received payload type may be used to detect malformed packets. It comprises two 1-byte
//			values. The first is for the payload channel, the second, for the optional separate signalling
//			channel. To disable either or both of the check functions, set the corresponding value to its
//			default value 0. (R,-W, setbycreate) (optional) (2-bytes)
//
//		Expected Ssrc
//			Expected SSRC: This attribute specifies the RTP synchronization source in the PSN to the TDM
//			direction. The received SSRC may be used to detect misconnection (stray packets). It comprises
//			two 4-byte values. The first is for the payload channel, the second, for the optional separate
//			signalling channel. To disable either or both of the check functions, set the corresponding
//			value to its default value 0. (R,-W, setbycreate) (optional) (8-bytes)
//
type RtpPseudowireParameters struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	rtppseudowireparametersBME = &ManagedEntityDefinition{
		Name:    "RtpPseudowireParameters",
		ClassID: 283,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xfc00,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1: Uint16Field("ClockReference", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2: ByteField("RtpTimestampMode", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3: Uint16Field("Ptype", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 3),
			4: Uint64Field("Ssrc", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5: Uint16Field("ExpectedPtype", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 5),
			6: Uint64Field("ExpectedSsrc", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 6),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

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