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

// SipAgentPerformanceMonitoringHistoryDataClassID is the 16-bit ID for the OMCI
// Managed entity SIP agent performance monitoring history data
const SipAgentPerformanceMonitoringHistoryDataClassID = ClassID(151) // 0x0097

var sipagentperformancemonitoringhistorydataBME *ManagedEntityDefinition

// SipAgentPerformanceMonitoringHistoryData (Class ID: #151 / 0x0097)
//	This ME collects PM data for the associated VoIP SIP agent. Instances of this ME are created and
//	deleted by the OLT.
//
//	For a complete discussion of generic PM architecture, refer to clause I.4.
//
//	Relationships
//		An instance of this ME is associated with a SIP agent config data or SIP config portal object.
//
//	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 corresponding SIP agent config data or to the SIP config
//			portal. If a non-OMCI configuration method is used for VoIP, there can be only one live ME
//			instance, associated with the SIP config portal, and with ME ID 0. (R, setbycreate) (mandatory)
//			(2-bytes)
//
//		Interval End Time
//			This attribute identifies the most recently finished 15-min interval. (R) (mandatory) (1-byte)
//
//		Threshold Data 1_2 Id
//			Threshold data 1/2 ID: This attribute points to an instance of the threshold data 1 ME that
//			contains PM threshold values. Since no threshold value attribute number exceeds 7, a threshold
//			data 2 ME is optional. (R,-W, setbycreate) (mandatory) (2-bytes)
//
//		Transactions
//			This attribute counts the number of new transactions that were initiated. (R) (optional)
//			(4-bytes)
//
//		Rx Invite Reqs
//			This attribute counts received invite messages, including retransmissions. (R) (optional)
//			(4-bytes)
//
//		Rx Invite Retrans
//			This attribute counts received invite retransmission messages. (R) (optional) (4-bytes)
//
//		Rx Noninvite Reqs
//			This attribute counts received non-invite messages, including retransmissions. (R) (optional)
//			(4-bytes)
//
//		Rx Noninvite Retrans
//			This attribute counts received non-invite retransmission messages. (R) (optional) (4-bytes)
//
//		Rx Response
//			This attribute counts total responses received. (R) (optional) (4-bytes)
//
//		Rx Response Retransmissions
//			This attribute counts total response retransmissions received. (R) (optional) (4-bytes)
//
//		Tx Invite Reqs
//			This attribute counts transmitted invite messages, including retransmissions. (R) (optional)
//			(4-bytes)
//
//		Tx Invite Retrans
//			This attribute counts transmitted invite retransmission messages. (R) (optional) (4-bytes)
//
//		Tx Noninvite Reqs
//			This attribute counts transmitted non-invite messages, including retransmissions. (R) (optional)
//			(4-bytes)
//
//		Tx Noninvite Retrans
//			This attribute counts transmitted non-invite retransmission messages. (R) (optional) (4-bytes)
//
//		Tx Response
//			This attribute counts the total responses sent. (R) (optional) (4-bytes)
//
//		Tx Response Retransmissions
//			This attribute counts total response retransmissions sent. (R) (optional) (4-bytes)
//
type SipAgentPerformanceMonitoringHistoryData struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	sipagentperformancemonitoringhistorydataBME = &ManagedEntityDefinition{
		Name:    "SipAgentPerformanceMonitoringHistoryData",
		ClassID: 151,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
			GetCurrentData,
		),
		AllowedAttributeMask: 0xfffe,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1:  ByteField("IntervalEndTime", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read), false, false, false, 1),
			2:  Uint16Field("ThresholdData12Id", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3:  Uint32Field("Transactions", CounterAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, true, false, 3),
			4:  Uint32Field("RxInviteReqs", CounterAttributeType, 0x1000, 0, mapset.NewSetWith(Read), false, true, false, 4),
			5:  Uint32Field("RxInviteRetrans", CounterAttributeType, 0x0800, 0, mapset.NewSetWith(Read), false, true, false, 5),
			6:  Uint32Field("RxNoninviteReqs", CounterAttributeType, 0x0400, 0, mapset.NewSetWith(Read), false, true, false, 6),
			7:  Uint32Field("RxNoninviteRetrans", CounterAttributeType, 0x0200, 0, mapset.NewSetWith(Read), false, true, false, 7),
			8:  Uint32Field("RxResponse", CounterAttributeType, 0x0100, 0, mapset.NewSetWith(Read), false, true, false, 8),
			9:  Uint32Field("RxResponseRetransmissions", CounterAttributeType, 0x0080, 0, mapset.NewSetWith(Read), false, true, false, 9),
			10: Uint32Field("TxInviteReqs", CounterAttributeType, 0x0040, 0, mapset.NewSetWith(Read), false, true, false, 10),
			11: Uint32Field("TxInviteRetrans", CounterAttributeType, 0x0020, 0, mapset.NewSetWith(Read), false, true, false, 11),
			12: Uint32Field("TxNoninviteReqs", CounterAttributeType, 0x0010, 0, mapset.NewSetWith(Read), false, true, false, 12),
			13: Uint32Field("TxNoninviteRetrans", CounterAttributeType, 0x0008, 0, mapset.NewSetWith(Read), false, true, false, 13),
			14: Uint32Field("TxResponse", CounterAttributeType, 0x0004, 0, mapset.NewSetWith(Read), false, true, false, 14),
			15: Uint32Field("TxResponseRetransmissions", CounterAttributeType, 0x0002, 0, mapset.NewSetWith(Read), false, true, false, 15),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "SIPAMD Rx invite req",
			1: "SIPAMD Rx invite req retransmission",
			2: "SIPAMD Rx noninvite req",
			3: "SIPAMD Rx noninvite req retransmission",
			4: "SIPAMD Rx response",
			5: "SIPAMD Rx response retransmission",
		},
	}
}

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