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

// VoipLineStatusClassID is the 16-bit ID for the OMCI
// Managed entity VoIP line status
const VoipLineStatusClassID = ClassID(141) // 0x008d

var voiplinestatusBME *ManagedEntityDefinition

// VoipLineStatus (Class ID: #141 / 0x008d)
//	The VoIP line status ME contains line status information for POTS ports using VoIP services. An
//	ONU that supports VoIP automatically creates or deletes an instance of this ME upon creation or
//	deletion of a PPTP POTS UNI.
//
//	Relationships
//		An instance of this ME is associated with a PPTP POTS UNI.
//
//	Attributes
//		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 PPTP POTS UNI. (R) (mandatory) (2-bytes)
//
//		Voip Codec Used
//			Reports the current codec used for a VoIP POTS port. Valid values are taken from [IETF RFC
//			3551], and are the same as specified in the codec selection attribute of the VoIP media profile.
//			This attribute is meaningful only if the VoIP port session type attribute is not idle.
//
//			0	PCMU
//
//			1	reserved
//
//			2	reserved
//
//			3	GSM
//
//			4	ITU-T G.723
//
//			5	DVI4, 8 kHz
//
//			6	DVI4, 16 kHz
//
//			7	LPC
//
//			8	PCMA
//
//			9	ITU-T G.722
//
//			10	L16, 2 channels
//
//			11	L16, 1 channel
//
//			12	QCELP
//
//			13	CN
//
//			14	MPA
//
//			15	ITU-T G.728
//
//			16	DVI4, 11.025 kHz
//
//			17	DVI4, 22.050 kHz
//
//			18	ITU-T G.729
//
//			(R) (mandatory) (2-bytes)
//
//		Voip Voice Server Status
//			14	Config done
//
//			15	Disabled by switch
//
//			(R) (mandatory) (1-byte)
//
//			Status of the VoIP session for this POTS port:
//
//			0	None/initial
//
//			1	Registered
//
//			2	In session
//
//			3	Failed registration - icmp error
//
//			4	Failed registration - failed tcp
//
//			5	Failed registration - failed authentication
//
//			6	Failed registration - timeout
//
//			7	Failed registration - server fail code
//
//			8	Failed invite - icmp error
//
//			9	Failed invite - failed tcp
//
//			10	Failed invite - failed authentication
//
//			11	Failed invite - timeout
//
//			12	Failed invite - server fail code
//
//			13	Port not configured
//
//		Voip Port Session Type
//			This attribute reports the current state of a VoIP POTS port session:
//
//			0	Idle/none
//
//			1	2way
//
//			2	3way
//
//			3	Fax/modem
//
//			4	Telemetry
//
//			5	Conference
//
//			(R) (mandatory) (1-byte)
//
//		Voip Call 1 Packet Period
//			This attribute reports the packet period for the first call on the VoIP POTS port. The value is
//			defined in milliseconds. (R) (mandatory) (2-bytes)
//
//		Voip Call 2 Packet Period
//			This attribute reports the packet period for the second call on the VoIP POTS port. The value is
//			defined in milliseconds. (R) (mandatory) (2-bytes)
//
//		Voip Call 1 Dest Addr
//			This attribute reports the DA for the first call on the VoIP POTS port. The value is an ASCII
//			string. (R) (mandatory) (25-bytes)
//
//		Voip Call 2 Dest Addr
//			This attribute reports the DA for the second call on the VoIP POTS port. The value is an ASCII
//			string. (R) (mandatory) (25-bytes)
//
//		Voip Line State
//			This attribute reports the state of the POTS line. This attribute may not be meaningful if the
//			POTS port is administratively locked, is operationally disabled, or is being tested. Code points
//			are assigned as follows:
//
//			0	Idle, on-hook
//
//			1	Off-hook dial tone
//
//			2 	Dialling
//
//			3	Ringing or FSK alerting/data
//
//			4	Audible ringback
//
//			5	Connecting
//
//			6	Connected
//
//			7	Disconnecting, audible indication
//
//			8	ROH, no tone
//
//			9	ROH with tone
//
//			10	Unknown or undefined
//
//			(R) (optional) (1 byte)
//
//		Emergency Call Status
//			(R) (Optional) (1-byte)
//
//			This attribute reports the current state of an emergency call session (when the ONU is the call
//			originator) on the VoIP POTS port. The ONU determines the presence of an originating emergency
//			call on the basis of the Emergency service number attribute of the VoIP feature access codes ME.
//
//			0--- No emergency call in progress
//
//			1--- Emergency call in progress
//
//			NOTE - The ONU may also be able to determine the presence of an emergency call on the basis of
//			other, unspecified information.
//
type VoipLineStatus struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	voiplinestatusBME = &ManagedEntityDefinition{
		Name:    "VoipLineStatus",
		ClassID: 141,
		MessageTypes: mapset.NewSetWith(
			Get,
		),
		AllowedAttributeMask: 0xff80,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: Uint16Field("VoipCodecUsed", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read), false, false, false, 1),
			2: ByteField("VoipVoiceServerStatus", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read), false, false, false, 2),
			3: ByteField("VoipPortSessionType", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, false, false, 3),
			4: Uint16Field("VoipCall1PacketPeriod", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read), false, false, false, 4),
			5: Uint16Field("VoipCall2PacketPeriod", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read), false, false, false, 5),
			6: MultiByteField("VoipCall1DestAddr", OctetsAttributeType, 0x0400, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read), false, false, false, 6),
			7: MultiByteField("VoipCall2DestAddr", OctetsAttributeType, 0x0200, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read), false, false, false, 7),
			8: ByteField("VoipLineState", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read), false, true, false, 8),
			9: ByteField("EmergencyCallStatus", UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read), true, true, false, 9),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

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