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

// CallControlPerformanceMonitoringHistoryDataClassID is the 16-bit ID for the OMCI
// Managed entity Call control performance monitoring history data
const CallControlPerformanceMonitoringHistoryDataClassID = ClassID(140) // 0x008c

var callcontrolperformancemonitoringhistorydataBME *ManagedEntityDefinition

// CallControlPerformanceMonitoringHistoryData (Class ID: #140 / 0x008c)
//	This ME collects PM data related to the call control channel. 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 an instance of the PPTP POTS UNI ME.
//
//	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, 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)
//
//		Call Setup Failures
//			This attribute counts call set-up failures. (R) (mandatory) (4-bytes)
//
//		Call Setup Timer
//			This attribute is a high water-mark that records the longest duration of a single call set-up
//			detected during this interval. Time is measured in milliseconds from the time an initial set-up
//			was requested by the subscriber until the time at which a response was provided to the
//			subscriber in the form of busy tone, audible ring tone, etc. (R) (mandatory) (4-bytes)
//
//		Call Terminate Failures
//			This attribute counts the number of calls that were terminated with cause. (R) (mandatory)
//			(4-bytes)
//
//		Analog Port Releases
//			This attribute counts the number of analogue port releases without dialling detected (abandoned
//			calls). (R) (mandatory) (4-bytes)
//
//		Analog Port Off_Hook Timer
//			Analog port off-hook timer: This attribute is a high water-mark that records the longest period
//			of a single off-hook detected on the analogue port. Time is measured in milliseconds. (R)
//			(mandatory) (4-bytes)
//
type CallControlPerformanceMonitoringHistoryData struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	callcontrolperformancemonitoringhistorydataBME = &ManagedEntityDefinition{
		Name:    "CallControlPerformanceMonitoringHistoryData",
		ClassID: 140,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
			GetCurrentData,
		),
		AllowedAttributeMask: 0xfe00,
		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("CallSetupFailures", CounterAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, false, false, 3),
			4: Uint32Field("CallSetupTimer", CounterAttributeType, 0x1000, 0, mapset.NewSetWith(Read), false, false, false, 4),
			5: Uint32Field("CallTerminateFailures", CounterAttributeType, 0x0800, 0, mapset.NewSetWith(Read), false, false, false, 5),
			6: Uint32Field("AnalogPortReleases", CounterAttributeType, 0x0400, 0, mapset.NewSetWith(Read), false, false, false, 6),
			7: Uint32Field("AnalogPortOffHookTimer", CounterAttributeType, 0x0200, 0, mapset.NewSetWith(Read), false, false, false, 7),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "CCPM call set-up fail",
			1: "CCPM set-up timeout",
			2: "CCPM call terminate",
			3: "CCPM port release with no dialling",
			4: "CCPM port offhook timeout",
		},
	}
}

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