/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 *
 * 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"

const MulticastSubscriberMonitorClassId ClassID = ClassID(311)

var multicastsubscribermonitorBME *ManagedEntityDefinition

// MulticastSubscriberMonitor (class ID #311)
//	This ME provides the current status of each port with respect to its multicast subscriptions. It
//	may be useful for status monitoring or debugging purposes. The status table includes all dynamic
//	groups currently subscribed by the port.
//
//	Relationships
//		Instances of this ME are created and deleted at the request of the OLT. One instance may exist
//		for each IEEE 802.1 UNI configured to support multicast subscription.
//
//	Attributes
//		Managed Entity Id
//			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 MAC bridge port configuration
//			data or IEEE 802.1p mapper ME. (R, setbycreate) (mandatory) (2 bytes)
//
//		Me Type
//			(R, W, setbycreate) (mandatory) (1 byte)
//
//		Current Multicast Bandwidth
//			Current multicast bandwidth: This attribute is the ONU's (BE) estimate of the actual bandwidth
//			currently being delivered to this particular MAC bridge port over all dynamic multicast groups.
//			(R) (optional) (4 bytes)
//
//		Join Messages Counter
//			Join messages counter: This attribute counts the number of times the corresponding subscriber
//			sent a join message that was accepted. When full, the counter rolls over to 0. (R) (optional)
//			(4 bytes)
//
//		Bandwidth Exceeded Counter
//			Bandwidth exceeded counter: This attribute counts the number of join messages that did exceed,
//			or would have exceeded, the max multicast bandwidth, whether accepted or denied. When full, the
//			counter rolls over to 0. (R) (optional) (4 bytes)
//
//		Ipv4 Active Group List Table
//			(R) (mandatory) (24N bytes)
//
//		Ipv6 Active Group List Table
//			(R) (optional) (58N bytes)
//
type MulticastSubscriberMonitor struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	multicastsubscribermonitorBME = &ManagedEntityDefinition{
		Name:    "MulticastSubscriberMonitor",
		ClassID: 311,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			GetNext,
			Set,
		),
		AllowedAttributeMask: 0XFC00,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, false, 0),
			1: ByteField("MeType", 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, false, 1),
			2: Uint32Field("CurrentMulticastBandwidth", 0, mapset.NewSetWith(Read), false, false, true, false, 2),
			3: Uint32Field("JoinMessagesCounter", 0, mapset.NewSetWith(Read), false, false, true, false, 3),
			4: Uint32Field("BandwidthExceededCounter", 0, mapset.NewSetWith(Read), false, false, true, false, 4),
			5: TableField("Ipv4ActiveGroupListTable", TableInfo{nil, 24}, mapset.NewSetWith(Read), false, false, false, 5),
			6: TableField("Ipv6ActiveGroupListTable", TableInfo{nil, 58}, mapset.NewSetWith(Read), false, true, false, 6),
		},
	}
}

// NewMulticastSubscriberMonitor (class ID 311 creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from the wire, about to be sent on the wire.
func NewMulticastSubscriberMonitor(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(multicastsubscribermonitorBME, params...)
}
