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

// VoipMediaProfileClassID is the 16-bit ID for the OMCI
// Managed entity VoIP media profile
const VoipMediaProfileClassID ClassID = ClassID(142)

var voipmediaprofileBME *ManagedEntityDefinition

// VoipMediaProfile (class ID #142)
//	The VoIP media profile ME contains settings that apply to VoIP voice encoding. This entity is
//	conditionally required for ONUs that offer VoIP services. If a non-OMCI interface is used to
//	manage VoIP signalling, this ME is unnecessary.
//
//	An instance of this ME is created and deleted by the OLT. A VoIP media profile is needed for
//	each unique set of profile attributes.
//
//	Relationships
//		An instance of this ME may be associated with one or more VoIP voice CTP MEs.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. (R, setbycreate)
//			(mandatory) (2-bytes)
//
//		Fax Mode
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Voice Service Profile Pointer
//			Voice service profile pointer: Pointer to a voice service profile, which defines parameters such
//			as jitter buffering and echo cancellation. (R,-W, setbycreate) (mandatory) (2-bytes)
//
//		Codec Selection 1st Order
//			(R,-W, set-by-create) (mandatory) (1-byte)
//
//		Packet Period Selection 1st Order
//			Packet period selection (1st order): This attribute specifies the packet period selection
//			interval in milliseconds. The recommended default value is 10-ms. Valid values are 10..30-ms.
//			(R,-W, set-by-create) (mandatory) (1-byte)
//
//		Silence Suppression 1st Order
//			Silence suppression (1st order): This attribute specifies whether silence suppression is on or
//			off. Valid values are 0-= off and 1-= on. (R,-W, set-by-create) (mandatory) (1-byte)
//
//		Codec Selection 2nd Order
//			Codec selection (2nd order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Packet Period Selection 2nd Order
//			Packet period selection (2nd order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Silence Suppression 2nd Order
//			Silence suppression (2nd order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Codec Selection 3rd Order
//			Codec selection (3rd order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Packet Period Selection 3rd Order
//			Packet period selection (3rd order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Silence Suppression 3rd Order
//			Silence suppression (3rd order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Codec Selection 4th Order
//			Codec selection (4th order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Packet Period Selection 4th Order
//			Packet period selection (4th order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Silence Suppression 4th Order
//			Silence suppression (4th order):	(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Oob Dtmf
//			OOB DTMF:	This attribute specifies out-of-band DMTF carriage. When enabled (1), DTMF signals are
//			carried out of band via RTP or the associated signalling protocol. When disabled (0), DTMF tones
//			are carried in the PCM stream. (R,-W, setbycreate) (mandatory) (1-byte)
//
//		Rtp Profile Pointer
//			RTP profile pointer: This attribute points to the associated RTP profile data ME. (R,-W,
//			setbycreate) (mandatory) (2-bytes)
//
type VoipMediaProfile struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	voipmediaprofileBME = &ManagedEntityDefinition{
		Name:    "VoipMediaProfile",
		ClassID: 142,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xffff,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1:  ByteField("FaxMode", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2:  Uint16Field("VoiceServiceProfilePointer", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3:  ByteField("CodecSelection1StOrder", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 3),
			4:  ByteField("PacketPeriodSelection1StOrder", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5:  ByteField("SilenceSuppression1StOrder", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 5),
			6:  ByteField("CodecSelection2NdOrder", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 6),
			7:  ByteField("PacketPeriodSelection2NdOrder", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 7),
			8:  ByteField("SilenceSuppression2NdOrder", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 8),
			9:  ByteField("CodecSelection3RdOrder", UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 9),
			10: ByteField("PacketPeriodSelection3RdOrder", UnsignedIntegerAttributeType, 0x0040, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 10),
			11: ByteField("SilenceSuppression3RdOrder", UnsignedIntegerAttributeType, 0x0020, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 11),
			12: ByteField("CodecSelection4ThOrder", UnsignedIntegerAttributeType, 0x0010, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 12),
			13: ByteField("PacketPeriodSelection4ThOrder", UnsignedIntegerAttributeType, 0x0008, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 13),
			14: ByteField("SilenceSuppression4ThOrder", UnsignedIntegerAttributeType, 0x0004, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 14),
			15: ByteField("OobDtmf", UnsignedIntegerAttributeType, 0x0002, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 15),
			16: Uint16Field("RtpProfilePointer", UnsignedIntegerAttributeType, 0x0001, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 16),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

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