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

// VoiceServiceProfileClassID is the 16-bit ID for the OMCI
// Managed entity Voice service profile
const VoiceServiceProfileClassID = ClassID(58) // 0x003a

var voiceserviceprofileBME *ManagedEntityDefinition

// VoiceServiceProfile (Class ID: #58 / 0x003a)
//	This ME organizes data that describe the voice service functions of the ONU. Instances of this
//	ME are created and deleted by the OLT.
//
//	Relationships
//		An instance of this ME may be associated with zero or more instances of a VoIP voice CTP by way
//		of a VoIP media profile.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. (R, setbycreate) (mandatory)
//			(2-bytes)
//
//		Announcement Type
//			This attribute specifies the treatment when a subscriber goes off hook but does not attempt a
//			call within the dial-tone timeout interval. Valid values include the following.
//
//			0x01	Silence
//
//			0x02	Reorder tone
//
//			0x03	Fast busy
//
//			0x04	Voice announcement
//
//			0xFF	Not specified; ONU is free to make its own choice.
//
//			(R,-W, setbycreate) (mandatory) (1-byte)
//
//		Jitter Target
//			This attribute specifies the target value of the jitter buffer in milliseconds. The system tries
//			to maintain the jitter buffer at the target value. The value 0 specifies dynamic jitter buffer
//			sizing. (R,-W, setbycreate) (optional) (2-bytes)
//
//		Jitter Buffer Max
//			This attribute specifies the maximum depth of the jitter buffer associated with this service in
//			milliseconds. The value 0 specifies that the ONU uses its internal default. (R,-W, set-by-
//			create) (optional) (2-bytes)
//
//		Echo Cancel Ind
//			The Boolean value true specifies that echo cancellation is on; false specifies off. (R,-W,
//			setbycreate) (mandatory) (1-byte)
//
//		Pstn Protocol Variant
//			This attribute controls which variant of POTS signalling is used on the associated UNIs. Its
//			value is equal to the [ITU-T E.164] country code. The value 0 specifies that the ONU uses its
//			internal default. (R,-W, set-by-create) (optional) (2-bytes)
//
//		Dtmf Digit Levels
//			This attribute specifies the power level of DTMF digits that may be generated by the ONU towards
//			the subscriber set. It is a 2s complement value referred to 1-mW at the 0 transmission level
//			point (TLP) (dBm0), with resolution 1-dB. The default value 0x8000 selects the ONU's internal
//			policy. (R, W, setbycreate) (optional) (2-bytes)
//
//		Dtmf Digit Duration
//			This attribute specifies the duration of DTMF digits that may be generated by the ONU towards
//			the subscriber set. It is specified in milliseconds. The default value 0 selects the ONU's
//			internal policy. (R, W, setbycreate) (optional) (2 bytes)
//
//		Hook Flash Minimum Time
//			This attribute defines the minimum duration recognized by the ONU as a switchhook flash. It is
//			expressed in milliseconds; the default value 0 selects the ONU's internal policy. (R, W,
//			setbycreate) (optional) (2 bytes)
//
//		Hook Flash Maximum Time
//			This attribute defines the maximum duration recognized by the ONU as a switchhook flash. It is
//			expressed in milliseconds; the default value 0 selects the ONU's internal policy. (R, W,
//			setbycreate) (optional) (2 bytes)
//
//		Tone Pattern Table
//			This attribute is a table, each of whose entries specifies a complex tone (or silence) and a
//			duration. By linking tones and silence together, possibly cyclically, continuous, varying or
//			interrupted tone sequences, repetitive or not, may be defined. A tone sequence is initiated by
//			pointing to the first tone pattern table entry that defines its parameters. Each entry is a
//			vector comprising the following components.
//
//			Index (1 byte): This component is simply an index into the table. It ranges from 1..255. In a
//			set operation, the value 0 in this field clears the table.
//
//			Tone on (1 byte): This Boolean component controls whether the tone is on (true) or off. If the
//			tone is off, the frequency and power fields are not meaningful.
//
//			Frequency 1 (2 bytes): This component specifies the frequency of one of the tone components in
//			hertz.
//
//			Power 1 (1 byte): This component specifies the power level of the corresponding frequency
//			component. It ranges from 0 (coded as 0) to  -25.5 (coded as 255)-dBm0 with 0.1-dB resolution.
//
//			Three additional pairs of frequency-power components may be specified to define a complex tone.
//			If a pair of possibilities is not to be used, its frequency field should be set to 0.
//
//			Frequency 2 (2 bytes)
//
//			Power 2 (1 byte)
//
//			Frequency 3 (2 bytes)
//
//			Power 3 (1 byte)
//
//			Frequency 4 (2 bytes)
//
//			Power 4 (1 byte)
//
//			The following pair of frequency-power components allows the composite tone to be modulated
//			(warble effect). If this effect is not to be used, the frequency should be set to 0.
//
//			Modulation frequency (2 bytes), hertz
//
//			Modulation power (1 byte), 0..25.5-dBm0
//
//			Duration (2 bytes): This component specifies the duration of the phase, in milliseconds. The
//			value 0 specifies that the phase endures indefinitely, i.e., until terminated by other events
//			such as call abandonment.
//
//			Next entry (1 byte): This component is a pointer to another entry in this same table, which
//			permits sequences of tones to be defined, possibly cyclically. A reference to a non-existent
//			table entry, or the value 0, indicates that the sequence should be terminated.
//
//			(R,-W) (optional) (N * 20 bytes)
//
//		Tone Event Table
//			This attribute is a table, each of whose entries specifies an event for which a tone is defined.
//			If the tone can be synthesized by a sequence of complex tones and silence, the event refers to
//			an entry in the tone pattern table. Otherwise, the event refers to a file name that is expected
//			to be recognized by the ONU environment. Each entry in the tone event table is a vector
//			comprising the following components.
//
//			Event (1 byte): This component is an enumeration of the events for which a tone may be defined.
//			The event component also serves as the index for the table. A set operation to event 0 causes
//			the table to be cleared.
//
//			Tone pattern (1 byte): This component specifies an entry point into the tone pattern table
//			attribute, to be invoked when the specified event occurs. The value 0 indicates that no tone
//			from the tone pattern table is to be played.
//
//			Tone file (2 bytes): This component points to a large string ME that contains the path and name
//			of a file containing a codec sequence to be played out. If no file is found after traversing
//			these links, no tone is played. The behaviour is unspecified if both tone pattern and tone file
//			are specified.
//
//			Tone file repetitions (1 byte): This component specifies the number of times the tone file is to
//			be repeated. The value 0 means that the file is to be repeated indefinitely until terminated by
//			some external event such as call abandonment.
//
//			Reserved (2 bytes)
//
//			(R,-W) (optional) (N * 7 bytes).
//
//		Ringing Pattern Table
//			This attribute is a table, each of whose entries specifies a ringing pattern and a duration. By
//			linking ringing and silence together, possibly cyclically, continuous or interrupted ringing
//			sequences, repetitive or not, may be defined. A ringing sequence is initiated by pointing to the
//			first ringing pattern table entry that defines its parameters. Each entry is a vector comprising
//			the following components.
//
//			Index (1 byte): This component is simply an index into the table. It ranges from 1..255. In a
//			set operation, the value 0 in this field clears the table.
//
//			Ringing on (1 byte): This Boolean component controls whether ringing is on (true) or off during
//			this interval.
//
//			Duration (2 bytes): This component specifies the duration of the ringing phase, in milliseconds.
//			The value 0 specifies that the phase endures indefinitely, i.e., until terminated by other
//			events such as call abandonment.
//
//			Next entry (1 byte): This component is a pointer to another entry in this same table, which
//			permits sequences of ringing bursts to be defined, possibly cyclically. A reference to a non-
//			existent table entry, or the value 0, indicates that the sequence should be terminated.
//
//			(R,-W) (optional) (N * 5 bytes).
//
//		Ringing Event Table
//			This attribute is a table, each of whose entries specifies an event for which a ringing sequence
//			is defined. If the ringing sequence can be generated as a sequence of power ringing and silent
//			intervals, the event refers to an entry in the ringing pattern table. Otherwise, the event
//			refers to a file name that is expected to be recognized by the ONU environment. Each entry is a
//			vector comprising the following components:
//
//			Event (1 byte): This component is an enumeration of the events for which a ringing sequence may
//			be defined. The event component also serves as the index for the table. A set operation with the
//			value 0 in this field causes the table to be cleared.
//
//			Ringing pattern (1 byte): This component specifies an entry point into the ringing pattern table
//			attribute, to be invoked when the specified event occurs. The value 0 indicates that no ringing
//			sequence is defined in the ringing pattern table.
//
//			Ringing file (2 bytes): This component points to a large string ME that contains the path and
//			name of a file containing a ring tone to be played out. If no file is found after traversing
//			these links, no ringing is played. The behaviour is unspecified if both ringing pattern and
//			ringing file fields are specified.
//
//			Ringing file repetitions (1 byte): This component specifies the number of times the ringing file
//			is to be repeated. The value 0 means that the file is to be repeated indefinitely until
//			terminated by some external event such as call abandonment.
//
//			Ringing text (2 bytes): This component points to a large string ME that contains a text string
//			to be displayed on the CPE device in conjunction with this event. A null pointer indicates that
//			no text is to be displayed.
//
//			(R,-W) (optional) (N * 7 bytes).
//
//		Network Specific Extensions Pointer
//			This attribute points to a network address ME that contains the path and name of a file
//			containing network specific parameters for the associated UNIs. The default value for this
//			attribute is 0xFFFF, a null pointer. (R,-W, set-by-create) (optional) (2-bytes)
//
type VoiceServiceProfile struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	voiceserviceprofileBME = &ManagedEntityDefinition{
		Name:    "VoiceServiceProfile",
		ClassID: 58,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			GetNext,
			Set,
			SetTable,
		),
		AllowedAttributeMask: 0xfffc,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1:  ByteField("AnnouncementType", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2:  Uint16Field("JitterTarget", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 2),
			3:  Uint16Field("JitterBufferMax", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 3),
			4:  ByteField("EchoCancelInd", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5:  Uint16Field("PstnProtocolVariant", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 5),
			6:  Uint16Field("DtmfDigitLevels", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 6),
			7:  Uint16Field("DtmfDigitDuration", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 7),
			8:  Uint16Field("HookFlashMinimumTime", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 8),
			9:  Uint16Field("HookFlashMaximumTime", UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 9),
			10: TableField("TonePatternTable", TableAttributeType, 0x0040, TableInfo{nil, 20}, mapset.NewSetWith(Read, Write), false, true, false, 10),
			11: TableField("ToneEventTable", TableAttributeType, 0x0020, TableInfo{nil, 7}, mapset.NewSetWith(Read, Write), false, true, false, 11),
			12: TableField("RingingPatternTable", TableAttributeType, 0x0010, TableInfo{nil, 5}, mapset.NewSetWith(Read, Write), false, true, false, 12),
			13: TableField("RingingEventTable", TableAttributeType, 0x0008, TableInfo{nil, 7}, mapset.NewSetWith(Read, Write), false, true, false, 13),
			14: Uint16Field("NetworkSpecificExtensionsPointer", UnsignedIntegerAttributeType, 0x0004, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 14),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			1: "File not found",
		},
	}
}

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